【问题标题】:WCF GZip Compression Request/Response ProcessingWCF GZip 压缩请求/响应处理
【发布时间】:2010-12-17 00:57:05
【问题描述】:

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

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

在客户端,我按照说明 herehere 将这个标头注入到 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


【解决方案1】:

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

【讨论】:

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

Here's an answer I gave 关于该主题的另一个问题。该问题是从 ADO.NET 数据服务的角度提出的,但我的回答纯粹是关于 WCF。

【讨论】:

    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 2019-05-07
    • 1970-01-01
    • 2012-02-12
    • 2015-04-01
    相关资源
    最近更新 更多