Сбой запроса большого веб-сервиса WCF с (400) неверным HTTP-запросом - PullRequest
74 голосов
/ 24 апреля 2009

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

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

Однако, если я позвоню в веб-сервис с 500 наименованиями, я получу ошибку 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>

Я посмотрел на a довольно большой число из ответов на на этот вопрос с безуспешно .

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

Ответы [ 9 ]

107 голосов
/ 24 апреля 2009

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

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

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

Кстати, пара советов по устранению неполадок при подключении к службам WCF:

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

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

7 голосов
/ 26 января 2011

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

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

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

7 голосов
/ 12 ноября 2010

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

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

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

<httpsTransport maxReceivedMessageSize="4194304" /> 
5 голосов
/ 12 мая 2011

На сервере в .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>
4 голосов
/ 27 января 2013

Вы также можете включить ведение журнала 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>
4 голосов
/ 24 апреля 2009

Может быть полезно отладить клиент, отключить Сервис \ Параметры \ Отладка \ Общие \ 'Включить только мой код', нажать Отладка \ Исключения \ 'Перехват всех исключений первого шанса' для исключений управляемого CLR и посмотреть на клиенте есть скрытое исключение до исключения протокола и до того, как сообщение попадет в сеть. (Я думаю, что это будет какой-то сбой сериализации.)

3 голосов
/ 05 марта 2012

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

3 голосов
/ 27 апреля 2011

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

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

1 голос
/ 03 марта 2017

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

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

Например, Следующее позволит до 300 МБ запросов

MaxAllowedContentLength = 314572800

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

...