大型WCF Web服务请求失败,并显示(400)HTTP错误请求


74

我遇到了这个看似常见的问题,无法解决。

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

但是,如果我用500个项目调用Web服务,则会收到Bad Request错误消息。

有趣的是,我在服务器上运行了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>

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

谁能帮我这个?


如果它没有到达服务器,则可能是发送的数据有问题。要求中可能包含一些非法字符?同样假设这是SOAP
Chad Grant

1
因此,您尝试将所有“最大”属性(例如maxReceivedMessageSize ...)设置为一个很高的数字吗?
mundeep

是的,它是SOAP。该请求应该没有任何问题-正如我说的那样,对于使用同一应用程序生成的最多50个元素,一切正常...
Damovisa

@mundeep-是的-我尝试将所有参数都设置为2147483647,但是那里没有运气。我链接到的某些页面实际上暗示对所有属性进行操作都是一件坏事……
Damovisa 2009年

Answers:


107

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

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

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

顺便说一句,一些解决连接WCF服务问题的技巧:

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

  • 在客户端上使用HTTP调试工具(例如Fiddler)检查HTTP通信。


1
太神奇了-仅此而已。谢谢您的答复!
Damovisa

2
感谢您提供启用跟踪的链接!
科林·戴斯蒙德

2
我尝试在结束时执行相同的操作,但无法品尝成功。
康坎

1
有用的博客文章:geekswithblogs.net/smyers/archive/2011/10/05/…-我只想指出阅读此答案的人,答案中的以上代码片段应进入绑定的绑定部分。例如:让绑定成为basicHttpBinding:<bindings> <basicHttpBinding> <binding ... /> <readerQuotas ... /> </ basicHttpBinding> </ bindings>-还有<readerQuotas maxArrayLength =“” />可能有被设置(我必须)。
dyslexicanaboko

7

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

从Silverlight向WCF发送大型XML

与使用customBinding一样,必须在web.config中的binding元素下的httpTransport元素上设置maxReceivedMessageSize:

<httpsTransport maxReceivedMessageSize="4194304" /> 

7

出于价值的考虑,使用.NET 4.0时的另一个注意事项是,如果在配置中找不到有效的终结点,则会自动创建和使用默认终结点。

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

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


@ user469104:很好的提示。谢谢。有没有一种方法可以强制服务器使用手动声明的终结点而不覆盖默认的ServiceHost?
拉索

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

调试客户端,关闭工具\选项\调试\常规\“启用我的代码”,单击调试\异常\“捕获所有优先机会异常”以获取托管CLR异常,这可能很有用。协议异常之前和消息生效之前,客户端上的异常例外。(我的猜测是某种序列化失败。)


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>

1
有时,最简单的答案是最好的。对我来说,我发现我在流响应调用中返回了一个空Stream对象。svclog在几秒钟内解决了这个问题。谢谢。
参议员

3

只想指出

除了MaxRecivedMessageSize,ReaderQuotas下还有一些属性,您可能会遇到限制项目数而不是大小限制。MSDN链接在这里


3

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

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

绑定名称=“” openTimeout =“ 00:10:00” closeTimeout =“ 00:10:00” receiveTimeout =“ 00:10:00” sendTimeout =“ 00:10:00” maxReceivedMessageSize =“ 2147483647” maxBufferPoolSize =“ 2147483647 “ maxBufferSize =” 2147483647“>


1

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

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

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

MaxAllowedContentLength = 314572800

希望它能对某人有所帮助!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.