【发布时间】:2010-12-17 00:57:05
【问题描述】:
如何让 WCF 客户端处理已被 IIS 压缩或压缩的服务器响应?
在 IIS 上,我按照说明 here 进行了有关如何使 .svc wcf 服务发出的所有响应(其中请求包含“Accept-Encoding: gzip, deflate”)的 IIS 6 gzip。
在客户端,我按照说明 here 和 here 将这个标头注入到 Web 请求中:“Accept-Encoding: gzip, deflate”。
Fiddler2 显示响应是二进制的,而不是普通的旧 Xml。
客户端崩溃并出现异常,基本上说没有 Xml 标头,这当然是真的。
在我的 IClientMessageInspector 中,应用在调用 AfterReceiveReply 之前崩溃。
一些进一步的说明:
(1) 我无法更改 WCF 服务或客户端,因为它们是由第 3 方提供的。但是,如果这是正确的方向,我可以通过配置附加行为和/或消息检查器。
(2) 我不想只压缩/解压缩肥皂正文,而是整个消息。
有什么想法/解决方案吗?
* 已解决 *
不可能编写 WCF 扩展来实现这些目标。相反,我遵循了这个 CodeProject article,它提倡一个辅助类:
public class CompressibleHttpRequestCreator : IWebRequestCreate
{
public CompressibleHttpRequestCreator()
{
}
WebRequest IWebRequestCreate.Create(Uri uri)
{
HttpWebRequest httpWebRequest =
Activator.CreateInstance(typeof(HttpWebRequest),
BindingFlags.CreateInstance | BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance,
null, new object[] { uri, null }, null) as HttpWebRequest;
if (httpWebRequest == null)
{
return null;
}
httpWebRequest.AutomaticDecompression =DecompressionMethods.GZip |
DecompressionMethods.Deflate;
return httpWebRequest;
}
}
另外,应用程序配置文件的补充:
<configuration>
<system.net>
<webRequestModules>
<remove prefix="http:"/>
<add prefix="http:"
type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
</webRequestModules>
</system.net>
</configuration>
似乎正在发生的事情是,WCF 最终要求 system.net 中的某个工厂或其他深层提供 HttpWebRequest 实例,我们提供将被要求创建所需实例的帮助器。
在 WCF 客户端配置文件中,只需要一个简单的 basicHttpBinding 即可,无需任何自定义扩展。
应用程序运行时,客户端Http请求包含header“Accept-Encoding: gzip, deflate”,服务端返回一个gzip压缩的web响应,客户端透明解压http响应后交给WCF。
当我尝试将此技术应用于 Web 服务时,我发现它不起作用。虽然辅助类的执行方式与 WCF 客户端使用时相同,但 http 请求不包含“Accept-Encoding: ...”标头。
为了使这项工作适用于 Web 服务,我必须编辑 Web 代理类,并添加此方法:
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
System.Net.HttpWebRequest rq = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
rq.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
return rq;
}
请注意,应用程序配置文件中的 CompressibleHttpRequestCreator 和块是否存在并不重要。对于 Web 服务,只有在 Web 服务代理中覆盖 GetWebRequest 才有效。
【问题讨论】:
-
为什么不将您的解决方案作为答案而不是问题的一部分发布,以便您接受它?
-
你的意思是什么:“为了让这个对 Web 服务起作用,我必须编辑 Web 代理类,并添加这个方法:”?什么是网络代理类??
标签: wcf http-headers gzip