WCF GZip压缩请求/响应处理 [英] WCF GZip Compression Request/Response Processing

查看:108
本文介绍了WCF GZip压缩请求/响应处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何让WCF客户端处理已被IIS GZip或Deflated的服务器响应?

How do I get a WCF client to process server responses which have been GZipped or Deflated by IIS?

在IIS上,我按照说明这里关于如何使IIS 6 gzip所有响应(其中请求包含由.svc wcf services发出的Accept-Encoding:gzip,deflate。

On IIS, I've followed the instructions here on how to make IIS 6 gzip all responses (where the request contained "Accept-Encoding: gzip, deflate") emitted by .svc wcf services.

在客户端上,我按照说明此处这里关于如何将此标题注入Web请求:Accept-Encoding:gzip,deflate。

On the client, I've followed the instructions here and here on how to inject this header into the web request: "Accept-Encoding: gzip, deflate".

Fiddler2显示响应是二进制的而不是普通的旧Xml。

Fiddler2 shows the response is binary and not plain old Xml.

客户端崩溃时出现异常,基本上说没有Xml标头,这是真的。

The client crashes with an exception which basically says there's no Xml header, which ofcourse is true.

在我的IClientMessageInspector中,a在调用AfterReceiveReply之前,pp会崩溃。

In my IClientMessageInspector, the app crashes before AfterReceiveReply is called.

进一步说明:

(1)我无法更改WCF服务或客户端,由第三方提供。但是,如果这是正确的方向,我可以通过配置附加行为和/或消息检查器。

(1) I can't change the WCF service or client as they are supplied by a 3rd party. I can however attach behaviors and/or message inspectors via configuration if this is the right direction to take.

(2)我不想压缩/解压缩只是肥皂体,但整个信息。

(2) I don't want to compress/uncompress just the soap body, but the entire message.

任何想法/解决方案?

*已解决*

无法编写WCF扩展来实现这些目标。相反,我遵循了这个CodeProject 文章,主张帮助类:

It was not possible to write a WCF extension to achieve these goals. Instead I followed this CodeProject article which advocate a helper class:

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;
    }
} 

以及对应用程序配置文件的补充:

and also, an addition to the application configuration file:

<configuration>
  <system.net>
    <webRequestModules>
      <remove prefix="http:"/>
      <add prefix="http:" 
            type="Pajocomo.Net.CompressibleHttpRequestCreator, Pajocomo" />
    </webRequestModules>
  </system.net>
</configuration>

似乎正在发生的事情是WCF最终要求system.net中的某些工厂或其他深处提供一个HttpWebRequest实例,我们提供将被要求创建所需实例的帮助器。

What seems to be happening is that WCF eventually asks some factory or other deep down in system.net to provide an HttpWebRequest instance, and we provide the helper that will be asked to create the required instance.

在WCF客户端配置文件中,只需要一个简单的basicHttpBinding即可,无需任何自定义扩展。

In the WCF client configuration file, a simple basicHttpBinding is all that is required, without the need for any custom extensions.

当应用程序运行时,客户端Http请求包含标题Accept-Encoding:gzip,deflate,服务器返回一个gzipped web响应,客户端在将其转发给WCF之前透明地解压缩http响应。

When the application runs, the client Http request contains the header "Accept-Encoding: gzip, deflate", the server returns a gzipped web response, and the client transparently decompresses the http response before handing it over to WCF.

当我尝试将此技术应用于Web服务时,我发现它没有工作。虽然辅助类的执行方式与WCF客户端使用的相同,但http请求不包含Accept-Encoding:...标题。

When I tried to apply this technique to Web Services I found that it did NOT work. Although the helper class was executed in the same was as when used by the WCF client, the http request did not contain the "Accept-Encoding: ..." header.

为了使这项工作适用于Web服务,我必须编辑Web代理类,并添加此方法:

To make this work for Web Services, I had to edit the Web Proxy class, and add this method:

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。

Note that it did not matter whether the CompressibleHttpRequestCreator and block from the application config file were present or not. For web services, only overriding GetWebRequest in the Web Service Proxy worked.

推荐答案

感谢您的WCF提示!我们将在我的商店为服务启用IIS压缩,我希望您的解决方案能够正常运行。
为Web服务做这项工作 - 你的意思是老派的SoapHttpProtocol客户吗?
因为SoapHttpProtocol类有一个内置的EnableDecompression属性,它会自动处理Compression标题和响应处理。

Thanks for your WCF tip! We're going to be enabling IIS compression for services at my shop, and I'm hoping your solution will work. By "To make this work for Web Services" - did you mean old school SoapHttpProtocol clients? Because the SoapHttpProtocol class has a built-in EnableDecompression property, which will automatically handle the Compression header and response handling.

这篇关于WCF GZip压缩请求/响应处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆