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

时间:2009-04-24 05:12:57

标签: c# .net 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.

我的客户端配置文件的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>

在服务器端,我的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>

我已looked at fairly large number answersthis question no success

任何人都可以帮我吗?

9 个答案:

答案 0 :(得分:107)

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

    <binding name="MyService.MyServiceBinding" 
           maxReceivedMessageSize="4194304">

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

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

  • 按照this MSDN article

  • 中的说明在服务器上启用跟踪
  • 在客户端上使用HTTP调试工具(例如Fiddler)来检查HTTP流量。

答案 1 :(得分:7)

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

Sending large XML from Silverlight to WCF

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

<httpsTransport maxReceivedMessageSize="4194304" /> 

答案 2 :(得分:7)

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

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

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

答案 3 :(得分: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>

答案 4 :(得分:4)

调试客户端可能很有用,关闭Tools \ Options \ Debugging \ General \'启用Just My Code',单击Debug \ Exceptions \'捕获所有第一次机会异常'以获取托管CLR异常,并查看是否在协议异常之前和消息到达线路之前,客户端上存在异常。 (我的猜测是某种序列化失败。)

答案 5 :(得分:4)

您还可以打开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>

答案 6 :(得分:3)

只想指出

除了MaxRecivedMessageSize之外,ReaderQuotas下还有属性,您可能会遇到项数限制而不是大小限制。 MSDN链接为here

答案 7 :(得分:3)

我找到了Bad Request 400问题的答案。

这是默认的服务器绑定设置。您需要添加到服务器和客户端默认设置。

binding name =“”openTimeout =“00:10:00”closeTimeout =“00:10:00”receiveTimeout =“00:10:00”sendTimeout =“00:10:00”maxReceivedMessageSize =“2147483647”maxBufferPoolSize =“2147483647”maxBufferSize =“2147483647”&gt;                                                 

答案 8 :(得分:1)

就我而言,即使在尝试所有解决方案并将所有限制设置为最大值后,它仍无法正常工作。最后我发现在IIS /网站上安装了一个Microsoft IIS过滤模块Url Scan 3.1,它有自己的限制来根据内容大小拒绝传入的请求并返回&#34; 404 Not found page& #34;

通过将%windir%\System32\inetsrv\urlscan\UrlScan.ini设置为所需的值,可以在MaxAllowedContentLength文件中更新该限制。

例如。以下将允许最多300 MB的请求

MaxAllowedContentLength = 314572800

希望它会帮助别人!