WCF GZip压缩请求/响应处理

24
如何使WCF客户端处理已由IIS GZipped或Deflated的服务器响应?
在IIS上,我按照这里的说明来使IIS 6 gzip所有由.svc wcf服务发出的响应(其中请求包含“Accept-Encoding:gzip,deflate”)。
在客户端上,我按照这里这里的说明来将此标头注入到Web请求中:“Accept-Encoding:gzip,deflate”。
Fiddler2显示响应是二进制的而不是旧的Xml。
客户端崩溃并引发异常,基本上说没有Xml标题,这当然是正确的。
在我的IClientMessageInspector中,在调用AfterReceiveReply之前应用程序崩溃。
一些进一步的说明:
(1)我不能更改WCF服务或客户端,因为它们由第三方提供。但是,如果这是正确的方向,我可以通过配置附加行为和/或消息检查器。
(2)我不想压缩/解压缩仅仅是soap正文,而是整个消息。
有任何想法/解决方案吗?
*已解决*

无法编写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最终会要求系统网络中某个深层工厂提供HttpWebRequest实例,而我们提供了将被要求创建所需实例的帮助程序。
在WCF客户端配置文件中,只需要一个简单的basicHttpBinding,无需任何自定义扩展。
当应用程序运行时,客户端Http请求包含头部"Accept-Encoding: gzip, deflate",服务器返回经过gzip压缩的Web响应,客户端在交给WCF之前透明地解压缩http响应。
当我尝试将这种技术应用于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才有效。

7
为什么不将你的解决方案发布为答案,而不是问题的一部分,这样你就可以接受它了?(Why not post your solution as an answer instead of part of the question, so you can accept it?) - Tim Lovell-Smith
5
“要使此功能适用于Web服务,我必须编辑Web代理类,并添加此方法。”的意思是什么?什么是Web代理类?“要使这项工作适用于Web服务,我必须编辑Web代理类并添加此方法。”这句话的意思是为了让某个功能在Web服务中能够使用,需要修改Web代理类并添加一个新的方法。Web代理类是一种编程代码,它可以帮助应用程序在客户端和服务器之间传递数据,在网络通信中起到重要的作用。 - Naor
2个回答

2

感谢你的WCF技巧!我们将启用IIS压缩服务,并希望您的解决方案能够奏效。 “要使Web服务起作用” - 你是指旧式的SoapHttpProtocol客户端吗? 因为SoapHttpProtocol类具有内置的EnableDecompression属性,可以自动处理压缩头和响应处理。


虽然OP在他的问题中提供的答案是有效的,但这是最好和正确的解决方案。应该被接受为答案。感谢指出这一点! - Marek

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接