大型WCF Web服务请求因(400)HTTP错误请求而失败

Dam*_*isa 74 .net c# wcf web-services

我遇到了这个明显常见的问题而且无法解决它.

如果我使用数组参数中相对较少的项目调用我的WCF Web服务(我已经测试了多达50个),一切都很好.

但是,如果我使用500个项目调用Web服务,则会收到错误请求错误.

有趣的是,我在服务器上运行Wireshark,看起来请求甚至没有命中服务器 - 客户端正在生成400错误.

例外是:

System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request.
Run Code Online (Sandbox Code Playgroud)

system.serviceModel我的客户端配置文件的部分是:

<system.serviceModel>
    <bindings>
        <wsHttpBinding>
            <binding name="WSHttpBinding_IMyService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                allowCookies="false">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2147483647"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00"
                    enabled="false" />
                <security mode="None">
                    <transport clientCredentialType="Windows" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="Windows" negotiateServiceCredential="true"
                        establishSecurityContext="true" />
                </security>
            </binding>
        </wsHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://serviceserver/MyService.svc"
            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMyService"
            contract="SmsSendingService.IMyService" name="WSHttpBinding_IMyService" />
    </client>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

在服务器端,我的web.config文件包含以下system.serviceModel部分:

<system.serviceModel>
    <services>
        <service name="MyService.MyService" behaviorConfiguration="MyService.MyServiceBehaviour" >
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyService.MyServiceBinding" contract="MyService.IMyService">
            </endpoint>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
    <bindings>
      <wsHttpBinding>
        <binding name="MyService.MyServiceBinding">
          <security mode="None"></security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="MyService.MyServiceBehaviour">
                <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                <serviceMetadata httpGetEnabled="true"/>
                <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                <serviceDebug includeExceptionDetailInFaults="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
</system.serviceModel>
Run Code Online (Sandbox Code Playgroud)

看了一个相当大的 数量回答这个问题,没有成功.

谁能帮我这个?

Joe*_*Joe 107

尝试在服务器上设置maxReceivedMessageSize,例如4MB:

    <binding name="MyService.MyServiceBinding" 
           maxReceivedMessageSize="4194304">
Run Code Online (Sandbox Code Playgroud)

默认(我认为65535)这么低的主要原因是降低拒绝服务(DoS)攻击的风险.您需要将其设置为大于服务器上的最大请求大小,以及客户端上的最大响应大小.如果您处于Intranet环境中,DoS攻击的风险可能很低,因此使用远高于您预期需要的值可能是安全的.

顺便提一下,有几个提示可以解决连接到WCF服务的问题:

  • 本MSDN文章中所述,在服务器上启用跟踪.

  • 在客户端上使用Fiddler等HTTP调试工具来检查HTTP流量.

  • 感谢您启用跟踪的链接! (2认同)
  • 我试图在我的结尾做同样的事情,但无法尝到成功. (2认同)

小智 7

我也得到了这个问题但是上面没有一个对我有用,因为我在经过长时间的挖掘后使用自定义绑定(对于BinaryXML)我在这里找到了答案: -

将大型XML从Silverlight发送到WCF

在使用customBinding时,必须在web.config中绑定元素下的httpTransport元素上设置maxReceivedMessageSize:

<httpsTransport maxReceivedMessageSize="4194304" /> 
Run Code Online (Sandbox Code Playgroud)


小智 7

对于它的价值,使用.NET 4.0时的另一个考虑因素是,如果在配置中找不到有效的端点,将自动创建并使用默认端点.

默认端点将使用所有默认值,因此如果您认为您具有maxReceivedMessageSize等值较大的有效服务配置,但配置有问题,您仍会收到400 Bad Request,因为默认端点将是创建和使用.

这是静默完成的,因此很难检测到.如果您打开服务器上的跟踪但没有其他指示(据我所知),您将看到此效果的消息(例如,"找不到服务端点,创建默认端点"或类似信息).


Bri*_*ian 5

调试客户端可能很有用,关闭 Tools\Options\Debugging\General\'Enable Just My Code',单击 Debug\Exceptions\'catch all first-chance exceptions' 以获取托管 CLR 异常,然后查看是否存在在协议异常之前和消息到达线路之前客户端上的异常。(我的猜测是某种序列化失败。)


RaS*_*Sor 5

在web.config中的.NET 4.0服务器中,您还需要更改默认绑定.设置以下3个参数:

 < basicHttpBinding>  
   < !--http://www.intertech.com/Blog/post/NET-40-WCF-Default-Bindings.aspx  
    - Enable transfer of large strings with maxBufferSize, maxReceivedMessageSize and maxStringContentLength
    -->  
   < binding **maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"**>  
      < readerQuotas **maxStringContentLength="2147483647"**/>            
   < /binding>
Run Code Online (Sandbox Code Playgroud)


Aar*_*man 5

您还可以打开 WCF 日志记录以获取有关原始错误的更多信息。这帮助我解决了这个问题。

将以下内容添加到您的 web.config,它将日志保存到 C:\log\Traces.svclog

<system.diagnostics>
    <sources>
        <source name="System.ServiceModel"
                  switchValue="Information, ActivityTracing"
                  propagateActivity="true">
            <listeners>
                <add name="traceListener"
                     type="System.Diagnostics.XmlWriterTraceListener"
                     initializeData= "c:\log\Traces.svclog" />
            </listeners>
        </source>
    </sources>
</system.diagnostics>
Run Code Online (Sandbox Code Playgroud)