【问题标题】:WCF Error - unexpected response: (400) Bad RequestWCF 错误 - 意外响应:(400)错误请求
【发布时间】:2023-03-23 06:44:01
【问题描述】:

我找不到这个问题的答案。大多数类似的帖子似乎都可以通过调整 web.config 文件中的一些最大大小设置来修复。但是,这些建议都没有解决我的问题。

为了提供更多背景知识,我将 asmx Web 服务移植到 Windows Azure 中托管的 WCF Web 服务。这个问题是在测试过程中出现的。如果我在一次调用中将少量事务传递给我的网络服务,它往往工作得很好。虽然当我的事务大小达到 50-60(事务)左右时,会出现此错误。序列化为 xml,文件大小在 300K 左右,所以没什么大不了的。但它确实倾向于尺寸问题。

另外,打开 WCF 跟踪,我发现出现以下异常:

System.ServiceModel.ProtocolException:已超出传入消息的最大消息大小配额 (65536)。要增加配额,请在适当的绑定元素上使用 MaxReceivedMessageSize 属性。

在 System.ServiceModel.Channels.HttpInput.ThrowHttpProtocolException(String message, HttpStatusCode statusCode, String statusDescription)

在 System.ServiceModel.Channels.HttpInput.ThrowMaxReceivedMessageSizeExceeded()

在 System.ServiceModel.Channels.HttpInput.ReadBufferedMessage(Stream inputStream)

在 System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(Exception& requestException)

在 System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext 上下文,动作回调)

因此,从例外情况来看,它看起来好像是我的 web.config 中关闭的设置之一,但它看起来像这样:

<system.serviceModel>
<behaviors>
  <serviceBehaviors>
    <behavior>
      <serviceMetadata httpGetEnabled="true"/>
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
    <behavior name="MetadataEnabled">
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <serviceMetadata httpGetEnabled="true"/>
      <useRequestHeadersForMetadataAddress>
        <defaultPorts>
          <add scheme="http" port="8081"/>
          <add scheme="https" port="444"/>
        </defaultPorts>
      </useRequestHeadersForMetadataAddress>
      <dataContractSerializer maxItemsInObjectGraph="111024000"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<services>
  <service name="Bandicoot.Core" behaviorConfiguration="MetadataEnabled">
    <endpoint name="HttpEndpoint"
              address=""
              binding="wsHttpBinding"
              bindingConfiguration="wsHttp"
              contract="Bandicoot.CORE.IRepricer" />
    <endpoint name="HttpMetadata"
              address="contract"
              binding="mexHttpBinding"
              bindingConfiguration="mexBinding"
              contract="Bandicoot.CORE.Stack" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/Core"/>
      </baseAddresses>
    </host>
  </service>
</services>
<bindings>
  <wsHttpBinding>
    <binding name="wsHttp" maxReceivedMessageSize="111024000" 
             messageEncoding="Text" maxBufferPoolSize="111024000" 
             textEncoding="UTF-8">
      <readerQuotas maxBytesPerRead="111024000"
                    maxArrayLength="111024000"
                    maxStringContentLength="111024000"/>
      <security mode="None"/>
    </binding>
  </wsHttpBinding>
  <mexHttpBinding>
    <binding name="mexBinding"/>
  </mexHttpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

有没有人有任何其他建议,或者我的 web.config 中是否有一些我没有看到的错误配置?

感谢您的建议!

编辑:这是我客户的 app.config 中的设置

<bindings>
<basicHttpBinding>
    <binding name="BasicHttpBinding_CORE" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="14194304" maxBufferPoolSize="14194304" maxReceivedMessageSize="14194304"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
        <readerQuotas maxDepth="1000" maxStringContentLength="111024000"
            maxArrayLength="111024000" maxBytesPerRead="1024000" maxNameTableCharCount="111024000" />
        <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
        </security>
    </binding>
</basicHttpBinding>

编辑:添加附加客户信息:

        <client>
        <endpoint address="http://localhost:92/CORE.svc" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_CORE" contract="Core.CORE"
            name="BasicHttpBinding_CORE" />
    </client>

编辑:尝试将服务绑定更改为 basicHttpBinding - 配置更改:

      <basicHttpBinding>
    <binding name="basicHttp" maxReceivedMessageSize="111024000"
             messageEncoding="Text" maxBufferPoolSize="111024000"
             textEncoding="UTF-8">
      <readerQuotas maxArrayLength="111024000" maxBytesPerRead="111024000" maxStringContentLength="111024000"/>
      <security mode="None" />
    </binding>
  </basicHttpBinding>

      <service name="Bandicoot.Core" behaviorConfiguration="MetadataEnabled">
    <endpoint binding="basicHttpBinding"
              bindingConfiguration="basicHttp"
              contract="Bandicoot.CORE.IRepricer" />
    <endpoint address="mex"
              binding="mexHttpBinding"
              bindingConfiguration="mexBinding"
              contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/Core"/>
      </baseAddresses>
    </host>
  </service>

还有客户端的 app.config 供参考:

        <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_CORE" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="100000000"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost:92/CORE.svc" binding="basicHttpBinding"
            bindingConfiguration="BasicHttpBinding_CORE" contract="Core.CORE"
            name="BasicHttpBinding_CORE" />
    </client>

【问题讨论】:

  • 您的客户端端点是否真的使用这些设置??
  • 您的服务定义了一个wsHttpBinding - 您的客户有basicHttpBinding 的设置......那些甚至匹配吗?另外 - 你没有向我们展示你客户配置的 &lt;client&gt;...&lt;/client&gt; 部分 - 这将是最有趣的!
  • @marc_s - 此客户端配置的大部分只是由 Visual Studio 中的“添加服务引用”功能自动生成的。由于我们的客户将使用此 Web 服务,如果他们不需要破解配置文件以使我们的服务正常工作,那将是更好的选择......这可能是它自己的另一个问题,所以现在我只想得到它工作。我已经发布了我的配置文件的客户端部分。如果您看到任何看起来不正确的内容,请告诉我。谢谢!
  • 有谁知道是否有办法确认服务器端实际使用的是什么绑定?

标签: asp.net wcf web-config azure


【解决方案1】:

您需要在客户端上设置maxReceivedMessageSize (您从服务返回的消息是传入的) - 在其app.configweb.config 中:

<system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="wsHttp" maxReceivedMessageSize="111024000" 
             messageEncoding="Text" maxBufferPoolSize="111024000" 
             textEncoding="UTF-8">
      <readerQuotas maxBytesPerRead="111024000"
                    maxArrayLength="111024000"
                    maxStringContentLength="111024000"/>
      <security mode="None"/>
    </binding>
  </wsHttpBinding>
  <mexHttpBinding>
    <binding name="mexBinding"/>
  </mexHttpBinding>
</bindings>
<client name="whatever">
    <endpoint name="HttpEndpoint"
        address=""
        binding="wsHttpBinding"
        bindingConfiguration="wsHttp"
        contract="Bandicoot.CORE.IRepricer" />
</client>
</system.serviceModel>

maxReceivedMessageSize 的默认值为 64K,除非您更改它。

【讨论】:

  • 对不起,我没有包括我的客户端配置,我也确实有这个设置。我也用我的 app.config 设置更新了原始问题。
  • 正如@marc_s 上面指出的,客户端似乎没有使用这些设置。错误信息清楚地显示当前限制为 64K。
  • 我用客户端配置更新了原始帖子。希望得到一些额外的建议。
  • @Brosto:正如我所料 - 服务定义了 wsHttpBinding 而客户端使用 basicHttpBinding - 这不一样!!你需要让这个阵容!您是否更新了服务(使用 wsHttp),然后您没有更新客户端,或者类似的东西??
  • 不,服务一直都有一个 wsHttpBinding,但是客户端出于某种原因自动生成了一个 basicHttpBinding。我确实尝试通过手动将客户端更改为 wsHttpBinding 来使这些相同,但它没有用。让我尝试将服务器更改为 basicHttpBinding,看看是否有任何影响。
【解决方案2】:

今天早上我终于想通了。问题是我的服务没有使用我认为的配置设置。原因?配置中的服务名称需要是正在实现的服务的完全限定路径。

我发现这个link 有助于解决这个问题。

我发现我的服务在没有将其指向实际端点的情况下工作有点奇怪,我猜它只是使用了一系列默认值,如果你想要不同的东西,你可以在 web.config 中配置它们?我认为这解释了为什么当我在客户端使用 web 服务时得到一个 basicHttpBinding,而不是 wsHttpBinding。

花了几天时间才弄明白,但很有教育意义。感谢您的建议!

【讨论】:

    【解决方案3】:

    我遇到了同样的错误,原因也被发现是配置错误。

    但在我的情况下,就像已经发布的 marc_s 一样,服务器端上的 ma​​xReceivedMessageSize 设置。服务器仍在使用其默认配置,低至 64 kb。

    现在听起来很明显,我花了很长时间才发现错误不在我的(客户端)端。

    我希望这对其他人有帮助。

    【讨论】:

      【解决方案4】:

      你好问题海报“Brosto”!

      这是对您 2010 年 11 月 17 日 15:29 的回答的补充。

      我们今天遇到了一个“有趣的”,或者我应该说是“教育性的”生产部署测试问题,这个问题花费了一天的大部分时间来解决,而且它实际上是由一次击键引起的。我们只是在完全部署 Web Farm 后发现问题消失后才确认问题的根源。

      这就是原因。当我们测试我们的生产部署并通过更改我们的 hosts 文件针对 “单服务器” 执行此操作时,我们绕过了负载均衡器,并且对单服务器的调用最终会通过默认的 http端口80!当我们针对 “负载均衡器” 进行测试时,负载均衡器对单个服务器的调用最终会通过负载均衡器定义的端口 81

      由于服务端点地址必须是“完全限定的”,以使服务能够找到其自定义绑定,因此必须更改单服务器上的 Services.config 文件以反映“ Single Server”与“Load Balanced Server”端点连接,如下:

      单服务器连接:

      endpoint address="http://www.myserver.com:80/Services/MyService.svc"
      

      负载平衡服务器连接:

      endpoint address="http://www.myserver.com:81/Services/MyService.svc"
      

      我的老板很早就正确地诊断出核心问题,说服务器的行为就像 自定义绑定被忽略,而是使用了默认值。 在向他展示了您的评论之后,您提到了“完全合格”服务端点地址的要求,他意识到主机文件重定向导致我们的浏览器请求转到单个服务器通过默认端口 80,而不是负载平衡端口 81,这实际上更改了完全限定的服务端点地址,这导致服务器忽略自定义绑定并恢复为默认设置。 请注意,它不是调用服务失败,只是绑定自定义绑定失败!

      希望下次我们使用自定义绑定对服务进行生产测试时有人会记得这个帖子:)

      【讨论】:

        猜你喜欢
        • 2019-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-09
        相关资源
        最近更新 更多