使用gzip压缩HttpWebRequest

我正在开发一个.NET 4.0控制台应用程序作为SOAP Web Service客户端,它将数据(POST)发送到第三方。 我无法控制服务器端的Web服务。 第三方确实提供了WSDL's使用,我能够导入它们并合理地使用它们。 但是,需要使用gzip压缩请求消息,并且我无法终身使用代理服务来弄清楚如何使用gzip

这个关于SO的主题让我相信,如果不能控制客户端和服务器代码,就无法压缩请求。 作为这一发现的结果,我在我的应用程序中编写了代码,以在XDocument对象中手动创建SOAP XML ; 然后,填充我之前编写的客户端应用程序要使用的WSDL代理类对象中的值。

此客户端的第一个要求是通过gzip发送压缩的消息。 经过一些研究,我看到答案很简单,就像在请求头中添加HttpRequestHeader.AcceptEncoding, "gzip, deflate"一样简单。 不幸的是,这样做似乎不起作用。

目前,我检索的证书不是真正的证书。 在部署到测试环境进行实际的服务测试之前,我试图使代码尽可能健全。

  1. 有没有办法通过代理调用( wsdl )压缩请求?
  2. 为了正确压缩HttpWebRequest我是否缺少一些东西?
  3. 可能会出现其他错误,导致返回错误消息?
    如果请求本身没问题,我希望有关身份validation的其他消息无效
  4. 有没有办法通过app.config进行压缩?

下一组要求我对如何处理/做什么感到困惑。 假设我已经将请求的ContentType设置为,我如何(以及什么)添加content-transfer-encoding片段以添加请求? 如果ContentType不正确,我该如何添加此信息?

具有MTOM编码附件的SOAP Evenlope的内容类型必须是“application / xop + xml”,content-transfer-encoding必须是8位。

我已经完成了下面代码的几次迭代,但是,我相信相关的代码片段是最简单的代码。 如果有其他信息有用,请告诉我。

创建HttpWebRequest的方法:

 private static HttpWebRequest CreateWebRequest(SoapAction action) { string url = GetUrlAddress(action); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate"); request.Headers.Add("SOAPAction", action.ToString()); request.ContentType = "application/xop+xml"; request.Accept = "text/xml"; request.Method = "POST"; request.ClientCertificates.Add(/* Retrieve X509Certificate Object*/); return request; } 

代码发送请求:

 using (Stream stream = request.GetRequestStream()) { soapXml.Save(stream); } 

用于检索响应的代码:
这是我检索正在发生的错误消息的方式

 try { using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { using (StreamReader reader = new StreamReader(response, Encoding.Default)) { File.AppendAllText(filePath, response.Headers.ToString()); File.AppendAllText(filePath, reader.ReadToEnd()); } } } catch (WebException ex) { using (var stream = ex.Response.GetResponseStream()) { using (var reader = new StreamReader(stream)) { Console.WriteLine(reader.ReadToEnd()); } } } 

收到错误消息:

必须使用HTTP压缩(RFC 1952 – GZIP)发送请求消息。

我想我能够通过在HttpWebRequest方法中添加以下内容来解决压缩错误消息:

 request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip"); 

更新了创建HttpWebRequest的方法:

 private static HttpWebRequest CreateWebRequest(SoapAction action) { string url = GetUrlAddress(action); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate"); request.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip"); request.Headers.Add("SOAPAction", action.ToString()); request.ContentType = "application/xop+xml"; request.Accept = "text/xml"; request.Method = "POST"; request.ClientCertificates.Add(/* Retrieve X509Certificate Object*/); return request; } 

使用以下代码替换当前代码以发送请求。

 using (Stream stream = request.GetRequestStream()) using (GZipStream gz = new GZipStream(stream, CompressionMode.Compress, false)) { soapXml.Save(gz); } 

编辑:可能需要使用“new GZipStream(stream,CompressionMode.Compress,true)”。 无法确定该构造函数参数将如何影响Web请求流。