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

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

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

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

Интересно, что я запустил Wireshark на сервере, и оказалось, что запрос даже не попадает на сервер. - на стороне клиента генерируется ошибка 400.

Исключение:

System.ServiceModel.ProtocolException: удаленный сервер вернул неожиданный ответ: (400) неверный запрос. --- ›System.Net.WebException: удаленный сервер возвратил ошибку: (400) неверный запрос.

Раздел 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>

У меня посмотрел довольно большой номер ответы на этот вопрос с безуспешно.

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


person Damovisa    schedule 24.04.2009    source источник
comment
Если он не попадает на сервер, возможно, что-то не так с отправляемыми данными. Может в запросе есть недопустимые символы? Также предполагая, что это SOAP   -  person Chad Grant    schedule 24.04.2009
comment
Итак, вы пробовали установить для всех своих максимальных атрибутов (например, maxReceivedMessageSize ...) действительно большое число?   -  person mundeep    schedule 24.04.2009
comment
Да, это мыло. И с запросом не должно быть ничего плохого - как я уже сказал, все работает нормально до 50 элементов, сгенерированных одним и тем же приложением ...   -  person Damovisa    schedule 24.04.2009
comment
@mundeep - ага - я попытался установить их все на 2147483647, но безуспешно. Некоторые страницы, на которые я ссылался, на самом деле предполагали, что это плохо делать это для всех атрибутов ...   -  person Damovisa    schedule 24.04.2009


Ответы (9)


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

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

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

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

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

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

person Joe    schedule 24.04.2009
comment
Удивительно - вот и все. Большое спасибо за ваш ответ! - person Damovisa; 24.04.2009
comment
Спасибо за ссылку для включения трассировки! - person Colin Desmond; 28.08.2009
comment
Я пытался сделать то же самое со своей стороны, но не смог ощутить успеха. - person Kangkan; 09.09.2010
comment
Полезное сообщение в блоге: geekswithblogs.net/smyers/archive/2011/10/05/ - я просто хочу указать людям, читающим этот ответ, что приведенный выше фрагмент кода в ответе должен попасть в раздел привязок вашего привязка. Пример: Пусть привязка будет базовой. комплект (пришлось). - person dyslexicanaboko; 14.12.2012

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

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

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

person user469104    schedule 26.01.2011
comment
@ user469104: Очень хороший совет. Спасибо. Есть ли способ заставить сервер использовать объявленную вручную конечную точку без перезаписи ServiceHost по умолчанию? - person RaSor; 12.05.2011

У меня тоже возникла эта проблема, однако ни одно из вышеперечисленных не сработало для меня, поскольку я использовал настраиваемую привязку (для BinaryXML) после долгих копаний. Я нашел здесь ответ: Отправка больших файлов XML из Silverlight в WCF

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

<httpsTransport maxReceivedMessageSize="4194304" /> 
person Mark Davies    schedule 12.11.2010

На сервере в .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>
</basicHttpBinding>
person RaSor    schedule 12.05.2011

Может быть полезно отладить клиент, отключить Tools \ Options \ Debugging \ General \ 'Enable Just My Code', щелкнуть Debug \ Exceptions \ 'поймать все исключения первого шанса' для управляемых исключений CLR и посмотреть, есть ли внутреннее исключение на клиенте до исключения протокола и до того, как сообщение попадет в сеть. (Я предполагаю, что это какая-то ошибка сериализации.)

person Brian    schedule 24.04.2009

Вы также можете включить ведение журнала 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>
person Aaron Hoffman    schedule 26.01.2013
comment
Иногда самые простые ответы оказываются лучшими. Что касается меня, я обнаружил, что возвращаю нулевой объект Stream в вызове ответа на поток. Svclog решил это за секунды. Спасибо. - person The Senator; 31.07.2013

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

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

person Yuan    schedule 26.04.2011

Я нашел ответ на проблему 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">
    <security mode="None"/>
    <readerQuotas maxStringContentLength="2147483647"/>
</binding>
person singh    schedule 05.03.2012

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

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

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

MaxAllowedContentLength = 314572800

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

person Sukhdeep Singh    schedule 03.03.2017