Вопрос

Я исследовал код 400 — BadRequest за последние два часа.Многие предложения направлены на то, чтобы убедиться, что атрибутbindingConfiguration установлен правильно, и в моем случае это так.

Теперь мне нужна ВАША помощь, прежде чем разрушать здание, в котором я нахожусь :-)

Я запускаю сервис WCF RestFull (очень легкий, использую этот ресурс для вдохновения: http://msdn.microsoft.com/en-us/magazine/dd315413.aspx), который (на данный момент) принимает XmlElement (POX), предоставленный через команду POST.

В настоящее время я ТОЛЬКО использую построитель запросов Fiddler перед реализацией настоящего клиента (поскольку это смешанные среды).

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

Вот мой файл web.config (для которого я даже включил клиентский тег (в отчаянные времена!)):

<system.web>
    <httpRuntime maxRequestLength="1500000" executionTimeout="180"/>
  </system.web>
  <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
    </diagnostics>
    <bindings>
      <webHttpBinding>
        <binding name="WebHttpBinding" maxReceivedMessageSize="1500000" maxBufferPoolSize="1500000" maxBufferSize="1500000" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
          <readerQuotas maxStringContentLength="1500000" maxArrayLength="1500000" maxBytesPerRead="1500000" />
          <security mode="None"/>
        </binding>
      </webHttpBinding>
    </bindings>
    <client>
      <endpoint address="" binding="webHttpBinding" bindingConfiguration="WebHttpBinding" contract="Commerce.ICatalogue"/>
    </client>
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="Catalogue">
        <endpoint address="" 
                  behaviorConfiguration="RestFull" 
                  binding="webHttpBinding"
                  bindingConfiguration="WebHttpBinding" 
                  contract="Commerce.ICatalogue" />
        <!-- endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" / -->
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="RestFull">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Заранее благодарим за любую помощь, которая приведет к успешному вызову с >65 КБ XML ;-)

Это было полезно?

Решение

Хорошо, этот действительно вызвал у меня трудности с разрешением, за которые я пощадлю других. Проблема заключалась в том, что я использовал <%@ ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory" Service="fullyQualifiedClassName" %>, что является хорошим и простым подходом к реализации на заводе.

Однако у этого подхода есть свои недостатки; поскольку в файле web.config не требуется настройка, класс WebServiceHostFactory по своему дизайну никогда не считывает данные из файла web.config. Я знаю; Я мог унаследовать от этого класса и внести соответствующие изменения, чтобы он действительно мог считываться из файла конфигурации, но это, казалось, немного выходило за рамки.

Моим решением было вернуться к более традиционному способу реализации WCF; <%@ ServiceHost Service="fullyQualifiedClassName" CodeBehind="~/App_Code/Catalogue.cs" %>, а затем используйте мои уже настроенные значения в файле web.config.

Вот мой модифицированный файл web.config (в отношении головной боли Maddox):

<system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="XmlMessageBinding" maxReceivedMessageSize="5000000" maxBufferPoolSize="5000000" maxBufferSize="5000000" closeTimeout="00:03:00" openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
          <readerQuotas maxStringContentLength="5000000" maxArrayLength="5000000" maxBytesPerRead="5000000" />
          <security mode="None"/>
        </binding>
      </webHttpBinding>
    </bindings>
    <services>
      <service name="fullyQualifiedClassName" behaviorConfiguration="DevelopmentBehavior">
        <endpoint name="REST" address="" binding="webHttpBinding" contract="fullyQualifiedInterfaceName" behaviorConfiguration="RestEndpointBehavior" bindingConfiguration="XmlMessageBinding" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="RestEndpointBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="DevelopmentBehavior">
          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
        <behavior name="ProductionBehavior">
          <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="false"/>
          <serviceMetadata httpGetEnabled="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

Еще одним преимуществом этого изменения является то, что теперь вы можете ссылаться на свою службу WCF-отдыха непосредственно из .NET; этого нельзя сделать с помощью модели Factory и моей реализации XmlElement с помощью решения.

Я надеюсь, что это может помочь другим с похожими проблемами ...

Другие советы

Я знаю, что это очень старый вопрос, и на него уже есть ответ...

В любом случае...

Что я сделал для решения этой «проблемы»: я создал Factory, унаследованную от WebServiceHostFactory, и создал собственный хост службы, унаследованный от WebServiceHost.

И в хосте я переопределил метод OnOpening вот так

protected override void OnOpening()
        {
            base.OnOpening();

            foreach (var endpoint in Description.Endpoints)
            {
                var binding = endpoint.Binding as System.ServiceModel.Channels.CustomBinding;

                foreach (var element in binding.Elements)
                {
                    var httpElement = element as System.ServiceModel.Channels.HttpTransportBindingElement;
                    if (httpElement != null)
                    {
                        httpElement.MaxBufferSize = 2147483647;
                        httpElement.MaxReceivedMessageSize = 2147483647;
                    }
                }
            }

        }

Я думаю, что у меня была та же проблема, но когда я настроил привязку по умолчанию для webHttp, то это сработало:

<bindings>
        <webHttpBinding>
            <binding maxReceivedMessageSize="2000000"
                      maxBufferSize="2000000">
                <readerQuotas maxStringContentLength="2000000"/>
            </binding>
        </webHttpBinding>
    </bindings>

Обратите внимание: на привязке нет имени.

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

WCF - исправление длины строки на стороне клиента исключения

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top