Dot-Net
如何在傳輸級別壓縮來自 WCF .NET 的 HTTP 請求?
我已經設法在 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 標頭。
如果您需要其他幫助,請告訴我。