在C#中将GZIP添加到WCF REST服务

我在C#.NET WCF Web服务上启用GZIP压缩时遇到了麻烦,希望有人可能知道我在App.conf配置文件中缺少的内容,或者在调用启动Web服务时需要多少额外function。代码。

我已经按照将GZIP压缩应用到WCF服务的链接指向下载Microsoft添加GZIP的示例,但该示例与我如何设置我的Web服务无关。

所以我的App.conf看起来像

                                    

我只是将配置和GZIP类从MS示例复制到我的项目中,并添加了我相关的Web服务配置。 我用来启动Windows服务的代码是:

 WebServiceHost webserviceHost = new WebServiceHost(typeof(MyService.Service1)); webserviceHost.Open(); 

webservice运行正常,但是当从Web浏览器拨打电话时,Fiddler没有检测到任何带有GZIP压缩的响应。 我还尝试以编程方式使用GZIP设置和运行Web服务,但失败了。 绿色我不知道还需要配置什么,任何建议都很棒

我深入研究了这一点并发现,因为我正在运行Web服务作为WebServiceHost对象,它必须使用WebServiceHost默认的WebHTTPBinding对象覆盖app.conf文件中的自定义GZIP绑定,这意味着任何即将发生的事情不会对Web服务进行编码。 为了解决这个问题,我想我会以编程方式将自定义GZIP绑定编写到代码中

 var serviceType = typeof(Service1); var serviceUri = new Uri("http://localhost:8080/webservice"); var webserviceHost = new WebServiceHost(serviceType, serviceUri); CustomBinding binding = new CustomBinding(new GZipMessageEncodingBindingElement(), new HttpTransportBindingElement()); var serviceEndPoint = webserviceHost.AddServiceEndpoint(typeof(IService), binding, "endpoint"); webserviceHost.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior { HelpEnabled = true }); webserviceHost.Open(); 

问题是它不允许与WebHttpBehavior进行自定义绑定。 但是如果我删除了这个行为,那么我的REST Web服务变得丑陋,并期望Stream对象作为我合同中的输入。 我不确定如何配置行为,所以任何帮助都很棒。

所以这是我花了好几天后才提出的程序化解决方案。 请注意,我不知道如何在app.config文件中配置解决方案,但只能通过代码。 首先按照此链接获取并修复Microsoft的编码示例中的GZIP类。 然后使用以下示例代码作为配置您自己的Web服务的基础。

 //Some class class to start up the REST web service public class someClass(){ public static void runRESTWebservice(){ webserviceHost = new WebServiceHost(typeof(Service1), new Uri("http://localhost:8080)); webserviceHost.AddServiceEndpoint(typeof(IService), getBinding(), "webservice").Behaviors.Add(new WebHttpBehavior()); webserviceHost.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true }); } //produces a custom web service binding mapped to the obtained gzip classes private static Binding getBinding(){ CustomBinding customBinding = new CustomBinding(new WebHttpBinding()); for (int i = 0; i < customBinding.Elements.Count; i++) { if (customBinding.Elements[i] is WebMessageEncodingBindingElement) { WebMessageEncodingBindingElement webBE = (WebMessageEncodingBindingElement)customBinding.Elements[i]; webBE.ContentTypeMapper = new MyMapper(); customBinding.Elements[i] = new GZipMessageEncodingBindingElement(webBE); } else if (customBinding.Elements[i] is TransportBindingElement) { ((TransportBindingElement)customBinding.Elements[i]).MaxReceivedMessageSize = int.MaxValue; } } return customBinding; } } //mapper class to match json responses public class MyMapper : WebContentTypeMapper{ public override WebContentFormat GetMessageFormatForContentType(string contentType){ return WebContentFormat.Json; } } //Define a service contract interface plus methods that returns JSON responses [ServiceContract] public interface IService{ [WebGet(UriTemplate = "somedata", ResponseFormat = WebMessageFormat.Json)] string getSomeData(); } //In your class that implements the contract explicitly set the encoding of the response in the methods you implement [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] public class Service1 : IService { public string getSomeData() { WebOperationContext.Current.OutgoingResponse.Headers[HttpResponseHeader.ContentEncoding] = "gzip"; return "some data"; } } 

我通过以下链接完成了大部分工作。

注意:有点让我感到困惑的是,微软没有将GZIP原生地构建到WCF中,这是任何返回大量数据的REST Web服务的重要组成部分。

为了回应您对WCF本身不支持的GZIP的评论,它已添加到.Net 4.5中。 看到这里 。

如果您使用的是RestService和IIS(> = 7.0),则不必自己执行此操作!

IIS 7支持动态压缩,允许自动压缩在您自己的应用程序(ASP.NET,MVC,WCF或其他!)中创建的内容。 该方案基于内容类型嗅探,因此它适用于任何类型的Web应用程序框架。

请在这里找到完整的教程。

出于某种原因,我无法让上述实现适用于使用Json +压缩的自托管WCF REST,仅适用于XML。

在环顾四周沮丧之后,终于从最近的博客中找到了解决方案。 希望这有助于任何仍在寻找同样事物的人。

https://blogs.msdn.microsoft.com/carlosfigueira/2016/02/23/using-automatic-format-selection-with-a-compression-encoder-in-self-hosted-scenarios/