Большой запрос веб-службы WCF с ошибкой (400) Ошибка HTTP-запроса

Я столкнулся с этой, по-видимому, общей проблемой и не смог ее решить.

Если я вызываю свой веб-сервис WCF с относительно небольшим количеством элементов в параметре массива (я тестировал до 50), все в порядке.

Однако, если я вызываю веб-службу с 500 элементами, я получаю ошибку "Плохой запрос".

Интересно, что я запустил 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>

Я посмотрел довольно большой номер ответы на this вопрос с без успеха.

Может ли кто-нибудь помочь мне с этим?

Ответ 1

Попробуйте установить maxReceivedMessageSize на сервере, например. до 4 МБ:

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

Основная причина, по которой значение по умолчанию (65535, я считаю) настолько низкое, заключается в уменьшении риска атак типа "отказ в обслуживании" (DoS). Вам нужно установить его больше, чем максимальный размер запроса на сервере, и максимальный размер ответа на клиенте. Если вы находитесь в среде Intranet, риск DoS-атак, вероятно, низкий, поэтому, вероятно, безопасно использовать значение намного выше, чем вы ожидаете.

Кстати, несколько советов по устранению неполадок, связанных с услугами WCF:

  • Включить трассировку на сервере, как описано в в этой статье MSDN.

  • Для проверки HTTP-трафика используйте средство отладки HTTP, например Fiddler.

Ответ 2

Я тоже получал эту проблему, но ни один из вышеперечисленных не работал у меня, поскольку я использовал пользовательскую привязку (для BinaryXML) после долгого рытья, я нашел ответ здесь: -

Отправка большого XML из Silverlight в WCF

Как я использую customBinding, maxReceivedMessageSize должен быть установлен в элементе httpTransport под элементом привязки в файле web.config:

<httpsTransport maxReceivedMessageSize="4194304" /> 

Ответ 3

Для чего стоит, дополнительное рассмотрение при использовании .NET 4.0 состоит в том, что если действительная конечная точка не найдена в вашей конфигурации, конечная точка по умолчанию будет автоматически создана и использована.

Конечная точка по умолчанию будет использовать все значения по умолчанию, поэтому, если вы считаете, что у вас есть действительная конфигурация службы с большим значением для maxReceivedMessageSize и т.д., но что-то не так с конфигурацией, вы все равно получите 400 Bad Request с по умолчанию конечная точка будет создана и использована.

Это делается тихо, поэтому его трудно обнаружить. Вы увидите сообщения об этом эффекте (например, "Нет конечной точки, найденной для Сервиса, создавая конечную точку по умолчанию" или аналогичную), если вы включите трассировку на сервере, но нет никаких других указаний (насколько мне известно).

Ответ 4

На сервере в .NET 4.0 в web.config вам также необходимо изменить привязку по умолчанию. Задайте следующие 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>

Ответ 5

Возможно, было бы полезно отладить клиент, отключить Tools\Options\Debugging\General\ "Включить только мой код", выбрать Debug\Exceptions\catch для всех исключений первого шанса для управляемых исключений CLR и посмотреть, на клиенте есть исключение под капотом до исключения протокола и до того, как сообщение попадет на провод. (Мое предположение было бы своего рода неудачей сериализации.)

Ответ 6

Вы также можете включить ведение журнала 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>

Ответ 7

Просто хочу указать

Помимо MaxRecivedMessageSize, есть атрибуты в ReadQuotas, вы можете набрать число элементов, а не ограничение размера. Ссылка MSDN здесь

Ответ 8

Я нашел ответ на проблему 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" >                                           

Ответ 9

В моем случае он не работал даже после того, как все решения были решены и все ограничения были максимальными. В последнее время я узнал, что на IIS/веб-сайт был установлен модуль фильтрации Microsoft IIS Url Scan 3.1 у него есть лимит на отклонение входящих запросов на основе размера контента и возврата "404 Не найденная страница".

Это ограничение можно обновить в файле %windir%\System32\inetsrv\urlscan\UrlScan.ini, установив MaxAllowedContentLength на требуемое значение.

Например, следующий позволит до 300 мб запросов

MaxAllowedContentLength = 314572800

Надеюсь, это поможет кому-то!