WCF GZip 压缩请求/响应处理

标签 wcf http-headers gzip

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

在 IIS 上,我已按照说明 here 进行操作关于如何使 IIS 6 gzip 由 .svc wcf 服务发出的所有响应(其中请求包含“Accept-Encoding: gzip, deflate”)。

在客户端上,我已按照说明 here 进行操作和 here关于如何将此 header 注入(inject)到 Web 请求中:“Accept-Encoding: gzip, deflate”。

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

客户端崩溃并出现异常,基本上表明没有 Xml header ,这当然是正确的。

在我的 IClientMessageInspector 中,应用程序在调用 AfterReceiveReply 之前崩溃。

一些进一步的说明:

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

(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: ...” header 。

为了使其适用于 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 和 block 是否存在并不重要。对于 Web 服务,只有重写 Web 服务代理中的 GetWebRequest 才有效。

最佳答案

感谢您的 WCF 提示!我们将在我的商店中为服务启用 IIS 压缩,我希望您的解决方案能够发挥作用。 “为了使这项工作适用于 Web 服务”——您是指老式 SoapHttpProtocol 客户端吗? 因为SoapHttpProtocol类有一个内置的EnableDecompression属性,它将自动处理压缩 header 和响应处理。

关于WCF GZip 压缩请求/响应处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1741768/

相关文章:

C# .NET 3.5 在使用基本示例时不复制流

c# - 服务仅在调试时工作

javascript - 你能从 javascript 使用 ASMX 网络服务吗?

google-chrome - 在 Chrome 中查看完整的重定向路径和 HTTP 状态代码

linux - 如何从 tar.gz 中仅提取所需的文件?

.net - 使用 KB2901983 对类 XmlWriterBackedStream 进行重大更改

http-headers - 我可以禁止在 AWS Cloudfront 上发布 Etag header 吗?

php - 跨域AJAX withCredentials,PHP返回 header 内容长度,但没有内容

Java-单线程和多线程的压缩差异

python - 如何在 Linux 上 gzip 文件并保留时间戳