2009-09-17 10 views
7

Sprawdziłem kod 400 - BadRequest z ostatnich dwóch godzin. Wiele sugestii dotyczy zapewnienia, że ​​atrybut bindingConfiguration jest ustawiony poprawnie, aw moim przypadku jest.Nie można ustawić maxReceivedMessageSize przez web.config

Teraz potrzebuję twojej pomocy przed zniszczeniem budynku jestem w :-)

uruchomić usługę WCF Restfull (bardzo lekki, korzystając z tego zasobu inspiracji: http://msdn.microsoft.com/en-us/magazine/dd315413.aspx), który (na razie) akceptuje XMLELEMENT (POX) dostarczone przez czasownik POST.

Obecnie używam narzędzia budującego żądania Fiddlera przed wdrożeniem prawdziwego klienta (ponieważ jest to środowisko mieszane).

Gdy robię to dla XML mniejszy niż 65K, działa dobrze - większy, wyrzuca ten wyjątek: Przekroczono maksymalny limit wielkości wiadomości dla wiadomości przychodzących (65536). Aby zwiększyć limit, użyj właściwości MaxReceivedMessageSize na odpowiednim elemencie wiązania.

Oto mój plik web.config (które nawet obejmowały client-tag (rozpaczliwych czasach)!):

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

Dzięki z góry za wszelką pomoc, prowadząc do udana rozmowy z> 65K XML; -)

Odpowiedz

12

W porządku, to naprawdę sprawiło mi trudność w rozwiązaniu, za co oszczędzę innym. Wyzwanie polegało na tym, że użyłem <%@ ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory" Service="fullyQualifiedClassName" %>, co jest przyjemnym i łatwym do wdrożenia podejściem do fabryki.

Jednak to podejście ma swoje wady; ponieważ w pliku web.config nie jest wymagana konfiguracja, klasa WebServiceHostFactory według projektu nigdy nie odczytuje pliku web.config. Wiem; Mogłem dziedziczyć z tej klasy i wprowadzać odpowiednie zmiany, aby rzeczywiście mogły być odczytane z pliku konfiguracyjnego, ale wydawało się to nieco poza zakresem.

Moim rozwiązaniem było powrót do bardziej tradycyjnego sposobu wdrażania WCF; <%@ ServiceHost Service="fullyQualifiedClassName" CodeBehind="~/App_Code/Catalogue.cs" %>, a następnie użyj moich już skonfigurowanych wartości w pliku web.config.

Oto mój zmodyfikowany plik web.config (w odniesieniu do Maddox głowy):

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

Inną zaletą tej zmiany jest to, że można teraz odwołać swoją usługę WCF reszta bezpośrednio z .NET; nie można tego zrobić przy użyciu modelu Factory i mojej implementacji XmlElement przez rozwiązanie.

Mam nadzieję, że może to pomóc innym z podobnymi problemami ...

+0

Miałem ten sam problem i pomyślałem, że to może być Fabryka, dzięki za potwierdzenie tego dla mnie. – Alex

+0

Awans, ponieważ to zachowanie jest naprawdę niejasne, a wniosek, że ServiceRoutes nie używa powiązań z Web.Config, nie wydaje się być udokumentowany w żadnym miejscu, ale zdecydowanie wydaje się, że tak jest. –

0

to jest wpis na blogu napisałem, że powiela ten problem z absolutnie minimalnym WCF serwera i klienta Piece:

WCF - Fixing client side string length exceptions

W szczególności może być potrzebna niestandardowa konfiguracja powiązania. Przynajmniej odtworzenie tej próbki może dać ci kilka pomysłów na konkretną sytuację.

+0

Witaj Michael, Dziękuję za twój wkład. Chociaż twój artykuł jest interesujący, moim dotychczasowym wyzwaniem jest doprowadzenie go do współpracy z Fiddler. Zakładam, że nie istnieje plik fiddler.config, więc nie mam ustawień klienta do ustawienia, co nie powinno mieć znaczenia, ponieważ jestem pewien, że Fiddler nie ma ograniczeń. Czy się mylę? –

+0

Więc działa dobrze przy użyciu wiersza poleceń lub innego programu klienta .NET? Nie miałbym pojęcia, jak ulepszyć Fiddlera, ale jeśli zweryfikujesz, że twoja strona serwera może obsłużyć> 65 000, problem jest zdecydowanie po stronie Skrzypka. –

+0

Wyzwanie polega na tym, że jest to lekka implementacja WCF przy użyciu klasy WebServiceHostFactory. O ile rozumiem, oznacza to, że nie mogę "Dodaj odwołania do usługi", ponieważ wymaga to formatu WSDL (dlaczego nie kontynuowałem twojego znakomitego łącza). –

6

Wiem, że to bardzo stary Pytania i to już ma odpowiedź ...

W każdym razie ...

Co zrobiłem, aby rozwiązać ten „problem” I stworzył fabrykę odziedziczone WebServiceHostFactory i stworzył Host Obsługa klienta odziedziczone WebServiceHost

I w przyjmującym I overrode metodę OnOpening jak ten

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; 
        } 
       } 
      } 

     } 
+0

To było bardzo pomocne. Użyłem tego w środowisku SharePoint, gdzie nie mogłem kontrolować web.config dla usługi. – MgSam

+1

To kołysze! Uwaga: nie używaj funkcji CreateBindings(), aby uzyskać powiązanie, które nie będzie działać. Użyj obsady, jak pokazano powyżej. Zwróć także uwagę na wykorzystanie poszczególnych fabryk. – CCondron

+0

Awesome !!! Dzięki! – zdrsh

6

myślę miałem ten sam problem, ale kiedy skonfigurowane default-wiążący dla webHttp to działało:

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

przestrzegać: brak nazwa w powiązaniu.

+1

Działa to doskonale, jeśli używasz System.ServiceModel.Activation.WebServiceHostFactory. – ROFLwTIME

Powiązane problemy