WCF压缩JSON响应

时间:2016-12-12 09:31:43

标签: c# wcf

我有一个基于JSON和POST方法的WCF Web服务,它有一个名为website的函数,返回一个包含2KB内容的JSON。此服务每秒有超过10K的请求。所以,我有很多文本数据要通过网络和I / O传递。我想我可以通过自动压缩响应来减少这个数据量。我知道通过在客户端设置标头来接受压缩内容,客户端可以通知服务器压缩内容是可接受的。但服务器如何发送压缩内容?

我已阅读this链接并实施它。但它仅适用于基于xml而非JSON的SOAP。我的意思是这个配置:

<customBinding>
  <binding name="BinaryCompressionBinding"> 
    <binaryMessageEncoding compressionFormat="GZip"/> 
    <httpTransport /> 
  </binding>
</customBinding> 

无法使用JSON,因为我们必须使用binaryMessageEncoding,因为JSON需要webMessageEncoding而且它不支持compressionFormat

另外,IIS动态压缩也无法帮助我。我添加了压缩JSON所需的标记。

更新 这是我的applicationhost.config:

<httpCompression directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files" minFileSizeForComp="0"> <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> <dynamicTypes> <add mimeType="application/json" enabled="true" /> <add mimeType="application/json; charset=utf-8" enabled="true" /> </dynamicTypes> </httpCompression>

1 个答案:

答案 0 :(得分:2)

作为替代方案和更多控制,您可以使用Message Inspector中的c#代码手动压缩您的回复。

对于WebApi,我使用委托处理程序做了类似的事情。您可以将我的代码包装到WCF的 Message Inspector 中。

Compress WebApi Response using delegating handler

Message Inspectors

或者使用IIS级压缩添加

<add mimeType="application/json; charset=utf-8" enabled="true" />

在您的applicationhost.config上。 See about json compression enabled mime type here

<强>更新 特别感谢@AnestisKivranoglou,我成功地为WCF的Json响应实现了gzip压缩。为了使@AnestisKivranoglou的答案更准确,我想在他的答案中添加一些细节。

您必须更改AfterReceiveRequest的{​​{1}}和BeforeSendReply,如下所示:

Message Inspector

这两段代码可以让您知道客户是否可以接受object IDispatchMessageInspector.AfterReceiveRequest(ref Message request, System.ServiceModel.IClientChannel channel, System.ServiceModel.InstanceContext instanceContext) { try { var prop = request.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty; var accept = prop.Headers[HttpRequestHeader.AcceptEncoding]; if (!string.IsNullOrEmpty(accept) && accept.Contains("gzip")) { var item = new DoCompressExtension(); OperationContext.Current.Extensions.Add(item); } } catch { } return null; } void IDispatchMessageInspector.BeforeSendReply(ref Message reply, object correlationState) { if (OperationContext.Current.Extensions.OfType<DoCompressExtension>().Count() > 0) { HttpResponseMessageProperty httpResponseProperty = new HttpResponseMessageProperty(); httpResponseProperty.Headers.Add(HttpResponseHeader.ContentEncoding, "gzip"); reply.Properties[HttpResponseMessageProperty.Name] = httpResponseProperty; } } !因此,您实现了gzip,可以在回复之前和接收之后捕获请求。现在,您需要使用this link实施behaviorExtensions。请注意,您必须使用this link解决bindingElementExtensions问题。最后,下面列出了一些变化:

  1. 将项目添加到GZip功能:
  2. ApplyConfiguration

    1. 将自定义绑定从case "webMessageEncoding":binding.innerBindingElement = new WebMessageEncodingBindingElement();break;更改为innerMessageEncoding="textMessageEncoding"
    2. 如果没有遗漏任何内容,您可以使用innerMessageEncoding="webMessageEncoding"方法检查并致电该服务,如果您在请求的标头中添加Post,则Json会收到压缩响应。如果您不添加此标题,您将收到未压缩的正常响应。