You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WCF客户端GZIP压缩配置疑问:代码位置与请求自动压缩实现

How to Enable GZip Compression for WCF BasicHttpBinding Client Requests and Responses

Hey there! Let's break this down step by step to get your WCF client sending compressed requests and handling compressed responses properly, fitting right into your existing code setup.

1. Where to add request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate?

In WCF, you can't directly tweak the underlying HttpWebRequest from the generated client proxy out of the box. Instead, you'll need to create a custom endpoint behavior that attaches a configured WebRequestHandler to handle response decompression. Here's how to do it:

First, add this helper behavior class to your client project:

using System.Net;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

public class DecompressionBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
        var handler = new WebRequestHandler();
        handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        bindingParameters.Add(new HttpClientHandlerProperty(handler));
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { }
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
    public void Validate(ServiceEndpoint endpoint) { }
}

Then, update your client call code to attach this behavior before making the request:

using (ServiceReference1.Srv1Client client = new ServiceReference1.Srv1Client())
{
    // Attach the decompression behavior to auto-unpack GZip/Deflate responses
    client.Endpoint.Behaviors.Add(new DecompressionBehavior());

    var data = client.GetData(longText, file);
}

This tells the underlying HTTP client to automatically decompress compressed responses from your IIS server.

2. How to make client requests (all parameters) automatically use GZip compression?

WCF doesn't include built-in request compression for BasicHttpBinding, so we'll add a custom message inspector to compress the request body before sending it, plus set the right HTTP header so IIS knows to decompress it.

First, add this message inspector and its associated behavior:

using System.IO;
using System.IO.Compression;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Xml;

public class GzipRequestInspector : IClientMessageInspector
{
    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        // Create a buffered copy of the original message to work with
        var buffer = request.CreateBufferedCopy(int.MaxValue);
        var originalMessage = buffer.CreateMessage();

        // Compress the message body
        var ms = new MemoryStream();
        using (var gzipStream = new GZipStream(ms, CompressionMode.Compress, true))
        {
            var writer = XmlDictionaryWriter.CreateBinaryWriter(gzipStream);
            originalMessage.WriteMessage(writer);
            writer.Flush();
        }

        // Build the compressed message
        ms.Position = 0;
        var compressedMessage = Message.CreateMessage(
            request.Version, 
            request.Headers.Action, 
            XmlDictionaryReader.CreateBinaryReader(ms, XmlDictionaryReaderQuotas.Max)
        );

        // Copy over all original headers
        foreach (var header in request.Headers)
        {
            compressedMessage.Headers.Add(header);
        }

        // Set the Content-Encoding header so IIS recognizes the compressed request
        var httpRequestProperty = new HttpRequestMessageProperty();
        httpRequestProperty.Headers["Content-Encoding"] = "gzip";
        compressedMessage.Properties[HttpRequestMessageProperty.Name] = httpRequestProperty;

        request = compressedMessage;
        return null;
    }

    public void AfterReceiveReply(ref Message reply, object correlationState) { }
}

// Behavior to attach the compression inspector to the client
public class GzipRequestBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(new GzipRequestInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }
    public void Validate(ServiceEndpoint endpoint) { }
}

Now, update your client code to include both behaviors:

using (ServiceReference1.Srv1Client client = new ServiceReference1.Srv1Client())
{
    // Handle decompressing incoming responses
    client.Endpoint.Behaviors.Add(new DecompressionBehavior());
    // Compress outgoing requests
    client.Endpoint.Behaviors.Add(new GzipRequestBehavior());

    var data = client.GetData(longText, file);
}

Quick Notes to Keep in Mind

  • Double-check your IIS configuration to ensure it's set up to accept compressed requests (you already enabled dynamic compression, but confirm that Content-Encoding: gzip is allowed for your WCF endpoints).
  • Large payloads (like your file byte array) will see the biggest performance gains from compression—smaller data might not get a huge boost, but it won't cause harm.
  • If you prefer config files over code, you can register these behaviors in your client's app.config instead, but the code approach is simpler for one-off client setups.

内容的提问来源于stack exchange,提问作者DooDoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:01:35