WCF - Як збільшити квоту розміру повідомлення


454

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

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

Максимальна квота розміру повідомлень для вхідних повідомлень (65536) перевищена. Щоб збільшити квоту, використовуйте властивість MaxReceivedMessageSize на відповідному прив'язувальному елементі.

Будь-яка допомога? Як збільшити квоту розміру повідомлення?


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

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

Чому вона за замовчуванням встановлена ​​настільки низькою? Безпека?
Чашки

@Компанії для безпеки дійсно. Якщо встановити квоту на повідомлення, наприклад, 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-атака, розмір за замовчуванням 64k вимагає дуже великої кількості клієнтів, щоб перемогти більшість серверів у ці дні.


20
Дякую .. Ці зміни потрібно внести у файл web.config клієнтської програми.
bugBurger

8
Також вам може знадобитися змінити його на сервері - у випадку, якщо вам потрібно буде надіслати великий набір даних у якості параметра до методу WCF.
Нейт

9
Його достатньо великий, щоб вмістити більшість повідомлень. Ви можете налаштувати це число відповідно до ваших потреб. Це в основному для запобігання атак типу DOS. Здійснення 20000000 дозволить розподіленій DOS-атаці бути ефективною, розмір за замовчуванням 64k вимагає дуже великої кількості клієнтів, щоб перемогти більшість серверів у цей день.
Nate

18
Для інших, хто цікавиться, я прочитав в іншому блозі, що максимальний розмір - 2147483647. 20000000 трохи менше, ніж це число, тому використання найменшого числа, з яким ви можете піти, не перериваючи послугу, має сенс.
ponosgeekdad

5
@Slauma Це було б потрібно змінити на сервері, якщо той параметр, що надходить, був занадто великим; в іншому випадку (і, швидше за все) зміни потрібно внести у файл конфігурації клієнта, оскільки занадто великий відповідь служби (а не її параметра).
Нейт

155

Якщо ви все ще отримуєте це повідомлення про помилку під час використання тестового клієнта WCF, це тому, що у клієнта є окремий параметр MaxBufferSize .

Щоб виправити проблему:

  1. Клацніть правою кнопкою миші на вузлі Config File у нижній частині дерева
  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

Клієнт WCF Test має власну конфігурацію клієнта.

Запустіть тестовий клієнт і прокрутіть донизу. Якщо двічі натиснути вузол Config File, ви побачите представлення XML. Як ви бачите, maxReceivedMessageSizeє 65536.

Щоб відредагувати це, клацніть правою кнопкою миші вузол дерева конфігурувати файли та виберіть Правка за допомогою SvcConfigEditor. Коли редактор відкриється, розгорніть Прив'язки та двічі клацніть прив’язку, яка автоматично генерується.

Тут можна редагувати всі властивості, в тому числі maxReceivedMessageSize. Закінчивши, натисніть Файл - Зберегти .

Нарешті, повернувшись до вікна тестового клієнта WCF, натисніть Інструменти - Параметри .

ПРИМІТКА : Зніміть прапорець Завжди регенерувати конфігурації при запуску служби .


2
Напевно, найкраща відповідь тут!
Харіс

3
зняти заявку через примітку, щоб зняти Always regenerate configпрапорець.
фур'єр

Найпростіше вирішити на мій погляд. Врятував мені головний біль.
Пляж Джаред

У vs2013 SvcConfigEditor заміняється на зміну конфігурації WCF, якщо люди шукають її.
ZoomVirus

Дякую. Я ламав голову на деякий час, змінюючи конфігурацію сервера знову і знову, коли проблема була з конфігурацією тестового клієнта!
Фахад

24

Я знайшов простий шлях

--- клацніть правою кнопкою миші файл конфігурації веб-конфігурації або програми та натисніть кнопку «РЕДИФТИРУВАННЯ WCF КОНФІГУРАЦІЯ» та перейдіть до bingdigs і вибору більш даного сервісу та праворуч показуйте maxReciveMessageSize дайте велику кількість ---


2
Це була чудова відповідь, я не знав, що можу редагувати звідси, спасибі
albert sh

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".

Я встановлюю у файлі applications.config (тобто. 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>


Чудово підходить для публікації вашої відповіді. Важливо, щоб значення "indingConfiguration "відповідало назві прив'язки. У вашому прикладі "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 точки введення в виконання, а не ту, що в проекті бібліотеки класів, що керує викликами Web-Service, якщо така є.

Наприклад, якщо ви отримуєте помилку під час виконання тестування одиниці, вам потрібно встановити відповідний конфігурацію в проекті тестування.


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.