WCF - Как увеличить квоту на размер сообщения


454

У меня есть служба WCF, которая возвращает 1000 записей из базы данных клиенту. У меня есть клиент ASP.NET WCF (я добавил ссылку на сервис в проекте веб-приложения asp.net для использования WCF).

При запуске клиентского приложения я получаю следующее сообщение:

Превышен максимальный размер квоты для входящих сообщений (65536). Чтобы увеличить квоту, используйте свойство MaxReceivedMessageSize соответствующего элемента привязки.

Любая помощь? Как увеличить квоту на размер сообщения?


У меня была та же самая проблема, но я только что получил недружественную сетевую ошибку 400, но решением было сообщение с размером сообщения ...
Мистер W

2
Я решил проблему, используя шаги, упомянутые в [ссылка] [1] [1]: stackoverflow.com/questions/7476853/…
Ram

Почему он установлен так низко по умолчанию? Безопасность?
Coops

@ Циклы для безопасности действительно. Например, установив квоту для сообщений, DDOS-атаки труднее (хотя бы немного) выполнить.
Питер ван Кекем

Ответы:


608

Вам нужно что-то вроде этого, чтобы увеличить квоты на размер сообщения, в файле App.config или Web.config :

<bindings>
    <basicHttpBinding>
        <binding name="basicHttp" allowCookies="true"
                 maxReceivedMessageSize="20000000" 
                 maxBufferSize="20000000"
                 maxBufferPoolSize="20000000">
            <readerQuotas maxDepth="32" 
                 maxArrayLength="200000000"
                 maxStringContentLength="200000000"/>
        </binding>
    </basicHttpBinding>
</bindings>

И используйте имя привязки в вашей конфигурации конечной точки, например

...
bindingConfiguration="basicHttp"
...

Обоснование значений простое, они достаточно велики, чтобы вместить большинство сообщений. Вы можете настроить это число под свои нужды. Низкое значение по умолчанию используется для предотвращения атак типа DOS. Создание 20000000 позволило бы обеспечить эффективную атаку распределенной DOS, размер по умолчанию, равный 64 КБ, потребовал бы очень большого числа клиентов для подавления большинства серверов в наши дни.


20
Спасибо. Это изменение необходимо внести в файл web.config клиентского приложения.
bugBurger

8
Вам также может понадобиться изменить его на сервере - в случае, если вам нужно отправить большой набор данных в качестве параметра в метод WCF.
Nate

9
Его достаточно большой, чтобы вместить большинство сообщений. Вы можете настроить это число под свои нужды. Это в основном там, чтобы предотвратить атаки типа DOS. Создание 20000000 позволит обеспечить эффективную атаку распределенной DOS, по умолчанию размер 64 КБ потребует очень большого числа клиентов для подавления большинства серверов в эти дни.
Nate

18
Для других, кто интересуется, я читал в другом блоге, что максимальный размер - 2147483647. 20000000 немного меньше этого числа, поэтому использование наименьшего числа, которое вы можете получить без прерывания обслуживания, имеет смысл.
Proudgeekdad

5
@Slauma Это необходимо изменить на сервере, если этот входящий параметр слишком велик; в противном случае (и более вероятно) изменение необходимо внести в файл конфигурации клиента, поскольку слишком велик ответ службы (а не ее параметр).
Nate

155

Если вы по-прежнему получаете это сообщение об ошибке при использовании тестового клиента WCF, это потому, что у клиента есть отдельная настройка MaxBufferSize .

Чтобы исправить проблему:

  1. Щелкните правой кнопкой мыши файл конфигурации узел в нижней части дерева.
  2. Выберите Изменить с помощью SvcConfigEditor

Появится список редактируемых настроек, включая MaxBufferSize.

Примечание: автоматически сгенерированные прокси-клиенты также устанавливают MaxBufferSize в 65536 по умолчанию.


8
Почему я всегда об этом забываю? +1
Джеймс Скемп

9
На vs2013 SvcConfigEditor заменяется на Изменить конфигурацию WCF, если люди ищут ее.
ZoomVirus,

Не удалось найти SVCconfigEditor?
Арул Сирджан

Вы найдете его в папке «Привязки», нажмите на привязку для службы, и она там.
Самер Алибхай

Если ваш файл конфигурации сгенерирован автоматически, вы обязательно должны сделать это следующим образом. Каждый раз, когда вы обновляете вашу ссылку, она восстанавливает app.config, и вам придется вручную изменить ее снова. Если вы измените его VS, новые изменения будут соответствовать выбранным вами настройкам.
kingfrito_5005

104

Если вы создаете свои привязки WCF динамически, вот код для использования:

BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.MaxReceivedMessageSize = Int32.MaxValue;
httpBinding.MaxBufferSize = Int32.MaxValue;
// Commented next statement since it is not required
// httpBinding.MaxBufferPoolSize = Int32.MaxValue;

Вы можете использовать его для инициализации. Понятно, что вы можете использовать его как конструктор.
aemre

45

Client Test WCF имеет собственную конфигурацию клиента.

Запустите тестовый клиент и прокрутите вниз. Если дважды щелкнуть узел «Файл конфигурации», вы увидите представление XML. Как вы можете видеть maxReceivedMessageSizeэто65536 .

Для редактирования щелкните правой кнопкой мыши узел дерева файла конфигурации и выберите «Редактировать с помощью». SvcConfigEditor . Когда редактор откроется, разверните узел «Привязки» и дважды щелкните автоматически созданную привязку.

Вы можете редактировать все свойства здесь, в том числе maxReceivedMessageSize. Когда вы закончите, нажмите Файл - Сохранить .

Наконец, когда вы вернетесь в окно тестового клиента WCF, нажмите Инструменты - Параметры .

ПРИМЕЧАНИЕ . Снимите флажок Всегда восстанавливать конфигурацию при запуске служб .


2
Наверное, лучший ответ здесь!
Харис

3
upvote из-за примечания, чтобы снять флажок с Always regenerate configопции.
фюрер

Проще всего решить на мой взгляд. Избавил меня от головной боли.
Джаред Бич

На vs2013 SvcConfigEditor заменяется на Изменить конфигурацию WCF, если люди ищут ее.
ZoomVirus,

Спасибо. Некоторое время ломал голову, менял конфигурацию сервера снова и снова, когда проблема была с конфигурацией Test Client!
Фахад

24

Я нашел легкий путь

--- щелкните правой кнопкой мыши файл конфигурации webconfig или app и выберите EDIT WCF CONFIGURATION и перейдите к bingdigs и выберите ваш сервис, а справа покажите, что maxReciveMessageSize выдает большое число ---


2
Это был отличный ответ, я не знал, что я могу редактировать отсюда, спасибо
Альберт

8

Я решаю проблему ... следующим образом

    <bindings>
  <netTcpBinding>
    <binding name="ECMSBindingConfig" closeTimeout="00:10:00" openTimeout="00:10:00"
      sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
      maxReceivedMessageSize="2147483647" portSharingEnabled="true">
      <readerQuotas maxArrayLength="2147483647" maxNameTableCharCount="2147483647"
          maxStringContentLength="2147483647" maxDepth="2147483647"
          maxBytesPerRead="2147483647" />
      <security mode="None" />
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="ECMSServiceBehavior">
      <dataContractSerializer ignoreExtensionDataObject="true" maxItemsInObjectGraph="2147483647" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceTimeouts transactionTimeout="00:10:00" />
      <serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="100"
        maxConcurrentInstances="100" />
    </behavior>
  </serviceBehaviors>
</behaviors>

20
Чем это отличается от моего решения? Кроме того, что вы включили все несущественные части вашей конфигурации, а также соответствующие детали, и вы выбрали максимально возможное значение вместо 200 м, которые я выбрал?
Нат

3
Контекст тоже хорош ... может быть, эти два ответа можно объединить?
Джефф

1
это настройка для сервера или клиента?
Джон Кенеди

8

Я решил проблему с Bing Maps WPF в своем проекте с помощью CalculateRoute (). Решением в моем случае была установка maxReceivedMessageSize и maxReceivedMessageSize для атрибута «httpTransport» для раздела «customBinding».

Я установил в файле application.config (es. MyApp.config) эту конфигурацию:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IGeocodeService" />
            <binding name="BasicHttpBinding_IRouteService" />
        </basicHttpBinding>
        <customBinding>
            <binding name="CustomBinding_IGeocodeService">
                <binaryMessageEncoding />
              <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                                maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
                                bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                                keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
                                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                                useDefaultWebProxy="true" />
            </binding>
            <binding name="CustomBinding_IRouteService">
                <binaryMessageEncoding />
              <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                                maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
                                bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                                keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
                                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                                useDefaultWebProxy="true" />
            </binding>
        </customBinding>
    </bindings>
    <client>
        <endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocodeService"
            contract="BingServices.IGeocodeService" name="BasicHttpBinding_IGeocodeService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc/binaryHttp"
            binding="customBinding" bindingConfiguration="CustomBinding_IGeocodeService"
            contract="BingServices.IGeocodeService" name="CustomBinding_IGeocodeService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRouteService"
            contract="BingServices.IRouteService" name="BasicHttpBinding_IRouteService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc/binaryHttp"
            binding="customBinding" bindingConfiguration="CustomBinding_IRouteService"
            contract="BingServices.IRouteService" name="CustomBinding_IRouteService" />
    </client>
</system.serviceModel>

6

<bindings>
  <wsHttpBinding>
    <binding name="wsHttpBinding_Username" maxReceivedMessageSize="20000000"          maxBufferPoolSize="20000000">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName" establishSecurityContext="false"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<client>
  <endpoint
            binding="wsHttpBinding"
            bindingConfiguration="wsHttpBinding_Username"
            contract="Exchange.Exweb.ExchangeServices.ExchangeServicesGenericProxy.ExchangeServicesType"
            name="ServicesFacadeEndpoint" />
</client>


Отлично подходит для размещения вашего ответа. Важно, чтобы значение «bindingConfiguration» соответствовало имени привязки. В вашем примере "wsHttpBinding_Username".
Бруно Биери

6

Для HTTP:

<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" allowCookies="true"
             maxReceivedMessageSize="20000000" 
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
        <readerQuotas maxDepth="200" 
             maxArrayLength="200000000"
             maxBytesPerRead="4096"
             maxStringContentLength="200000000"
             maxNameTableCharCount="16384"/>
    </binding>
  </basicHttpBinding>
</bindings>

Для TCP:

<bindings>
  <netTcpBinding>
    <binding name="tcpBinding"
             maxReceivedMessageSize="20000000"
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
      <readerQuotas maxDepth="200"
           maxArrayLength="200000000"
           maxStringContentLength="200000000"
           maxBytesPerRead="4096"
           maxNameTableCharCount="16384"/>
    </binding>
  </netTcpBinding>
</bindings>

ВАЖНЫЙ:

Если вы попытаетесь передать сложный объект, который имеет много связанных объектов (например, древовидную структуру данных, список, который содержит много объектов ...), связь не будет установлена ​​независимо от того, как вы увеличили квоты. В таких случаях вы должны увеличить количество содержащихся объектов:

<behaviors>
  <serviceBehaviors>
    <behavior name="NewBehavior">
      ...
      <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

Это maxItemsInObjectGraphбыло (быстрое) решение для меня. Но, увеличивая это, вы должны подумать о том, является ли лучшим решением для вашего приложения запрашивать данные в виде кусков, в отличие от огромного графа объектов, который может напрягать ресурсы.
Пол

6

Для меня все, что мне нужно было сделать, это добавить maxReceivedMessageSize="2147483647"в клиент app.config. Сервер остался нетронутым.


5

Еще одна важная вещь, чтобы рассмотреть из моего опыта ..

Я настоятельно советую НЕ максимизировать maxBufferPoolSize, потому что буферы из пула никогда не освобождаются, пока домен приложения (то есть пул приложений) не перезапустится.

Период большого трафика может привести к использованию большого количества памяти и никогда не освобождать ее.

Подробнее здесь:


3

Не забывайте, что будет учитываться app.config точки входа выполнения, а не тот, который находится в проекте библиотеки классов, управляющем вызовами веб-службы, если он есть.

Например, если вы получили ошибку во время выполнения модульного теста, вам нужно настроить соответствующий конфиг в проекте тестирования.


0

я получил эту ошибку при использовании этих настроек на web.config

System.ServiceModel.ServiceActivationException

Я установил настройки следующим образом:

      <service name="idst.Controllers.wcf.Service_Talks">
    <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_TalksAspNetAjaxBehavior"
      binding="webHttpBinding" contract="idst.Controllers.wcf.Service_Talks" />
  </service>
  <service name="idst.Controllers.wcf.Service_Project">
    <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_ProjectAspNetAjaxBehavior"
      binding="basicHttpBinding" bindingConfiguration="" bindingName="largBasicHttp"
      contract="idst.Controllers.wcf.Service_Project" />
  </service>
</services>

<bindings>
<basicHttpBinding>
    <binding name="largBasicHttp" allowCookies="true"
             maxReceivedMessageSize="20000000"
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
        <readerQuotas maxDepth="32"
             maxArrayLength="200000000"
             maxStringContentLength="200000000"/>
    </binding>
</basicHttpBinding>


4
Итак, вы исправили свою проблему, используя ответ Нейта, а затем опубликовали его как свой собственный. Не круто.
arcain

Ответ @arcain Nates был очень общим, с использованием названий акций и цифр, которые можно ожидать часто. Этот ответ не был украден, это просто правильный ответ. Поскольку есть только один правильный ответ, его обязательно нужно будет повторить.
kingfrito_5005

@ kingfrito_5005 «Правильный» ответ уже был здесь, когда ответчик опубликовал это. Он довольно четко поднял bindingsэлемент Нейта и разместил его как часть своего ответа. Эти 2000000ценности довольно разные.
Arcain

@ arcain, я не согласен, это очень стандартные ценности, моя компания также использует их в наших обязательных элементах.
kingfrito_5005
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.