2

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

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

此客户端的第一个要求是发送压缩的消息gzip。经过一些研究,我发现答案很简单,只需将 ' 添加HttpRequestHeader.AcceptEncoding, "gzip, deflate"到请求标头即可。不幸的是,这样做似乎没有用。

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

  1. 有没有办法通过代理调用(wsdl)压缩请求?
  2. 为了正确压缩,我是否缺少某些东西HttpWebRequest
  3. 可能还有其他问题会导致返回错误消息吗?
    如果请求本身是 OK ,我会期望与身份验证有关的不同消息无效
  4. 有没有办法通过压缩来完成app.config

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

带有 MTOM 编码附件的 SOAP Evenlope 的内容类型必须是“application/xop+xml”,并且内容传输编码必须是 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) 发送。

4

2 回答 2

2

我想我可以通过在方法中添加以下内容来解决压缩错误消息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;
}
于 2016-01-28T19:47:36.030 回答
1

使用以下代码代替您当前的代码来发送请求。

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

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

于 2016-01-28T05:24:11.257 回答