Dot-Net

如何在傳輸級別壓縮來自 WCF .NET 的 HTTP 請求?

  • May 24, 2013

我已經設法在 ASP.NET 上啟用入站 HTTP 壓縮(即壓縮 HTTP請求,而不僅僅是響應),但我現在在客戶端(C#/.NET 4.0 應用程序)上苦苦掙扎。

我想:

  • 添加 HTTP 標頭 Content-Encoding: gzip
  • 使用 GZip 壓縮 HTTP 正文

到 WCF 通道發出的所有出站 HTTP 請求。

到目前為止不起作用的解決方案:

  • 我可以壓縮消息,IClientMessageInspector但它不考慮整個 HTTP 正文,因為信封沒有壓縮。
  • 對於自定義消息編碼器也是如此,壓縮消息而不是信封,對 HTTP 請求標頭沒有影響。

知道如何IHttpModule在客戶端模仿行為(參見初始響應)嗎?

這裡描述的消息編碼器應該可以完成這項工作。

我已經使用從上述文章中的連結下載的範例(來自此的 InstallDrive\WF_WCF_Samples\WCF\Extensibility\MessageEncoder\Compression 項目)和 Fiddler 進行了測試。

請注意,MSDN 範例有一個錯誤,您需要修復它才能使其正常工作。在GZipMessageEncoderFactory類,CompressBuffer方法中,下面這行

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, bufferedBytes.Length - messageOffset);

應該替換為

ArraySegment<byte> byteArray = new ArraySegment<byte>(bufferedBytes, messageOffset, totalLength);

應用上述修復後,整個消息正文將被壓縮。

為了檢查壓縮是否正確,您可以使用 Fiddler 的 AutoDecode 選項。Content-Encoding: gzip但是,AutoDecode 僅在消息具有HTTP 標頭 時才解壓縮該消息。

將 HTTP 標頭添加到 WCF 消息呼叫並不嚴格,因為 WCF 設計為與傳輸無關,並且 WCF 應用程序不應處理特定於特定傳輸方法的元素。

但是,出於此應用程序的目的,我可以使用以下程式碼來實現:

public string Echo(string input)
{
   using (OperationContextScope opScope = new OperationContextScope((IContextChannel)base.Channel))
   {
       HttpRequestMessageProperty reqProps = new HttpRequestMessageProperty();
       reqProps.Headers["Content-Encoding"] = "gzip";
       OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = reqProps;

       return base.Channel.Echo(input);
   }
}

Echo 是 MSDN 範例中的客戶端方法之一,在其中我正在訪問目前操作上下文以添加 HTTP 標頭。

如果您需要其他幫助,請告訴我。

引用自:https://stackoverflow.com/questions/4416177