Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to set maxReceivedMessageSize through web.config

I have now investigated the 400 - BadRequest code for the last two hours. A lot of sugestions goes towards ensuring the bindingConfiguration attribute is set correctly, and in my case, it is.

Now, I need YOUR help before destroying the building i am in :-)

I run a WCF RestFull service (very lightweight, using this resource for inspiration: http://msdn.microsoft.com/en-us/magazine/dd315413.aspx) which (for now) accepts an XmlElement (POX) provided through the POST verb.

I am currently ONLY using Fiddler's request builder before implementing a true client (as this is mixed environments).

When I do this for XML smaller than 65K, it works fine - larger, it throws this exception: The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

Here is my web.config file (which I even included the client-tag for (desperate times!)):

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

Thanks in advance for any help leading to succesfull call with >65K XML ;-)

like image 253
gimlichael Avatar asked Sep 17 '09 16:09

gimlichael


1 Answers

All right, this one really caused me a hard time resolving, which I will spare others for. The challenge was in the fact, that I used the <%@ ServiceHost Factory="System.ServiceModel.Activation.WebServiceHostFactory" Service="fullyQualifiedClassName" %>, which is a nice and easy factory implementation approach.

However, this approach has it drawbacks; since no configuration is needed in the web.config file, the WebServiceHostFactory class by design does not ever read from the web.config file. I know; I could inherit from this class, and make the appropriate changes so it may indeed read from the config file, but this seemed a little out of scope.

My solution was to go back to the more traditional way of implementing the WCF; <%@ ServiceHost Service="fullyQualifiedClassName" CodeBehind="~/App_Code/Catalogue.cs" %>, and then use my already configured values in the web.config file.

Here is my modified web.config file (with respect to Maddox headache):

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

Another benefit of this change is, that you can now reference your WCF-rest service directly from .NET; this cannot be done using the Factory model and my implementation of XmlElement through out the solution.

I hope this can help others with similar issues ...

like image 143
gimlichael Avatar answered Oct 29 '22 00:10

gimlichael