.net 使用HttpWebRequest发出超过4KB的SOAP请求会导致500个内部服务器错误

.net 使用HttpWebRequest发出超过4KB的SOAP请求会导致500个内部服务器错误,.net,xml,vb.net,soap,httpwebrequest,.net,Xml,Vb.net,Soap,Httpwebrequest,当请求大小很大时,我在访问SOAP服务时遇到了真正的问题。当进行较短的SOAP调用时,所使用的方法(HttpWebRequest)工作得很好,但只要XML的大小超过4KB,我就可以在网络日志中看到请求被截断,最终导致目标服务器出现500个内部服务器错误。我还必须将客户端证书附加到调用,并且在这种情况下无法通过引用连接到web服务,因此使用HttpWebRequest Private Function GetResponse(ByVal sSoapUri As String, ByVal sSoa

当请求大小很大时,我在访问SOAP服务时遇到了真正的问题。当进行较短的SOAP调用时,所使用的方法(HttpWebRequest)工作得很好,但只要XML的大小超过4KB,我就可以在网络日志中看到请求被截断,最终导致目标服务器出现500个内部服务器错误。我还必须将客户端证书附加到调用,并且在这种情况下无法通过引用连接到web服务,因此使用HttpWebRequest

Private Function GetResponse(ByVal sSoapUri As String, ByVal sSoapMessage As String, ByVal sSoapAction As String, ByVal bAttachCert As Boolean, _cert As X509Certificate) As XmlDocument
    Try
        Dim oHttpReq As HttpWebRequest = DirectCast(WebRequest.CreateDefault(New Uri(sSoapUri)), HttpWebRequest)
        oHttpReq.ContentType = "text/xml; charset=utf-8"
        oHttpReq.Method = "POST"
        oHttpReq.Accept = "text/xml"
        oHttpReq.Headers.Add("soapaction", sSoapAction)
        oHttpReq.ServicePoint.Expect100Continue = False  ' <-- I've tried this both on and off to no avail
        If bAttachCert Then oHttpReq.ClientCertificates.Add(_cert)
        Dim oReqStream As New StreamWriter(oHttpReq.GetRequestStream(), Encoding.UTF8)
        oReqStream.Write(sSoapMessage)  '<-- This string is in just over 4K in length
        oReqStream.Flush()
        oReqStream.Close()

        Dim oHttpResp As HttpWebResponse = TryCast(oHttpReq.GetResponse(), HttpWebResponse)
        Dim oRespStream As Stream = oHttpResp.GetResponseStream()
        oHttpReq = Nothing
        Dim oXmlResp As New XmlDocument
        oXmlResp.Load(oRespStream)
        oRespStream.Flush()
        oRespStream.Close()
        Return oXmlResp
    Catch ex As WebException
        Return Nothing
    End Try
End Function
这是一个C#实现,我在处理大请求时使用过,没有失败。这种方法在将soap信封放入请求流方面有点不同,因为我构建了一个XDocument来表示soap请求,然后将其保存到请求流中。还要注意request.Timeout设置

您也应该首先考虑,如果您正在调用的服务对其接受的请求大小有限制。

希望这能给你一些想法

    public XDocument GetResponse(XDocument soapRequest)
    {
        //service point manager
        ServicePointManager.DefaultConnectionLimit = 5;
        ServicePointManager.Expect100Continue = false;

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("your soap endpoint");
        request.Headers.Add("SOAPAction", "your soap action");

        //set credentials
        request.CookieContainer = new CookieContainer();
        request.Credentials = "credentials if you need them";

        //set compression
        request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
        request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        request.ContentType = "text/xml;charset=\"utf-8\"";

        //set verb
        request.Method = "POST";

        //set connection properties
        request.KeepAlive = true;  //15 sec on server side
        request.Timeout = Timeout.Infinite;

        //insert SOAP envelope into the request
        using (Stream stream = request.GetRequestStream())
        {
            soapRequest.Save(stream);
        }

        //get response from server
        WebResponse response = request.GetResponse();

        //read response stream
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            if (reader != null)
            {
                return XDocument.Load(reader);
            }
            else
            {
                return null;
            }
        }
    }

得知我的邮件没有被截断

这方面的一个主要问题是,我的日志记录的maxdatasize设置为1024,因此在编写日志时,它们看起来被截断了,但实际上它们都存在。当我将maxdatasize键设置为大于发送的数据时,这一点变得很明显。摘自下面的最终配置部分:

<system.diagnostics>
    <sources>
      <source name="System.Net" tracemode="includehex" maxdatasize="8192">
        <listeners>
          <add name="System.Net"/>
        </listeners>
      </source>
      <source name="System.Net.Sockets" tracemode="includehex" maxdatasize="8192">
        <listeners>
          <add name="System.Net"/>
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="System.Net" value="Verbose"/>
      <add name="System.Net.Sockets" value="Verbose"/>
    </switches>
    <sharedListeners>
      <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\network.log"/>
    </sharedListeners>
    <trace autoflush="true"/>
  </system.diagnostics>


内部服务器500错误是由于服务器端的一个完全不相关的问题造成的。

谢谢Doug-我尝试了以上两种方法,即使用所采用的各种技术编辑我的当前版本,而且绝对是这样,它也造成了同样的问题。我确信请求被截断为4KB—当我格式化为XDocument时,截断点会移动,当我再次编辑请求XML时,截断点也会相应移动。我还检查了,服务提供商将接受大于4KB的数据,并且他们的日志也显示了被截断的请求。这让我快发疯了!再次感谢您的帮助。只是好奇:为什么要使用HttpWebRequest来实现这一点,而不是“添加服务引用”?不幸的是,由于它将在最终的实时环境中运行的体系结构,我不能这么做-如果它能做到这一点的话:(我不明白-你为什么不认为“添加服务引用”?)是否有效?为什么您认为需要这样做?您没有该服务的“开发”实例吗?即使您没有,也只需让您的操作人员对生产中的服务运行svcuti命令,并让他们向您提供WSDL或其他元数据。然后您可以使用“添加服务引用”并指定磁盘上的WSDL文件。您将数据发布到哪个web服务器?可能存在限制…尝试使用完全不同的客户端实现(例如soapUI)将数据发布到服务。如果问题仍然存在,则会出现在发布端。谢谢,在我阅读此响应之前,我一直假设我的soap请求也被截断。我想“打印1024个…”应该是一个提示
    public XDocument GetResponse(XDocument soapRequest)
    {
        //service point manager
        ServicePointManager.DefaultConnectionLimit = 5;
        ServicePointManager.Expect100Continue = false;

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create("your soap endpoint");
        request.Headers.Add("SOAPAction", "your soap action");

        //set credentials
        request.CookieContainer = new CookieContainer();
        request.Credentials = "credentials if you need them";

        //set compression
        request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
        request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        request.ContentType = "text/xml;charset=\"utf-8\"";

        //set verb
        request.Method = "POST";

        //set connection properties
        request.KeepAlive = true;  //15 sec on server side
        request.Timeout = Timeout.Infinite;

        //insert SOAP envelope into the request
        using (Stream stream = request.GetRequestStream())
        {
            soapRequest.Save(stream);
        }

        //get response from server
        WebResponse response = request.GetResponse();

        //read response stream
        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            if (reader != null)
            {
                return XDocument.Load(reader);
            }
            else
            {
                return null;
            }
        }
    }
<system.diagnostics>
    <sources>
      <source name="System.Net" tracemode="includehex" maxdatasize="8192">
        <listeners>
          <add name="System.Net"/>
        </listeners>
      </source>
      <source name="System.Net.Sockets" tracemode="includehex" maxdatasize="8192">
        <listeners>
          <add name="System.Net"/>
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="System.Net" value="Verbose"/>
      <add name="System.Net.Sockets" value="Verbose"/>
    </switches>
    <sharedListeners>
      <add name="System.Net" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\network.log"/>
    </sharedListeners>
    <trace autoflush="true"/>
  </system.diagnostics>