Unable to set maxReceivedMessageSize through web.config
Asked Answered
D

4

8

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

Deanery answered 17/9, 2009 at 16:37 Comment(0)
D
13

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

Deanery answered 18/9, 2009 at 14:22 Comment(2)
I was having the same problem and I thought it might be the Factory, thanks for confirming this for me.Referent
Upvote because this behavior is really unclear and the conclusion that ServiceRoutes aren't using bindings from Web.Config doesn't seem to be documented anywhere but definitely seems to be the case.Wallet
T
7

I know this is a very old Question and it already has an answer...

Anyway...

What I did to solve this "issue" I created a Factory inherited from WebServiceHostFactory and created a Custom Service Host inherited from WebServiceHost

And in the host I overrode the OnOpening method like this

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

        }
Telamon answered 19/1, 2012 at 12:1 Comment(3)
This was very helpful. I used this in a SharePoint environment where I could not control the web.config for the service.Testerman
This rocks! Note: do not use CreateBindings() to get the binding it will not work. Use the cast as listed above. Also note the use of the particular factories.Toothed
For MultipleBaseAddressWebServiceHost service: foreach (var endpoint in this.Description.Endpoints) { var binding = endpoint.Binding as System.ServiceModel.WebHttpBinding; binding.MaxReceivedMessageSize = int.MaxValue; }Submersed
G
6

I think i had the same issue, but when i configured the default-binding for webHttp then it worked:

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

Observe: no name on the binding.

Gorgeous answered 4/10, 2012 at 8:36 Comment(1)
This works perfect if you are using System.ServiceModel.Activation.WebServiceHostFactory.Fruma
H
0

This is a blog entry I wrote that reproduces this problem with an absolutely minimal WCF server and client piece:

WCF - Fixing client side string length exceptions

In particular, you may need a Custom Binding Configuration. At least reproducing this sample may give you some ideas for your particular situation.

Hobble answered 17/9, 2009 at 17:56 Comment(5)
Hi Michael, Thank you for your input. Allthough your article is interesting, my challenge so far is to get it to work with Fiddler. I assume that no fiddler.config exists, so I have no client settings to set, which should not matter, as I am quite sure, that Fiddler does not have a limitation. Am I wrong here?Deanery
So it's working fine using a command line or other .NET client program? I would have no idea how to tweak Fiddler, but if you've verified your server side can handle > 65k, the problem is definitely on the Fiddler side.Hobble
The challenge is, that this is a down-to-earth lightweight WCF implementation using the WebServiceHostFactory class. As far as I understand, this means, that I cannot "Add a service reference" because it requires the WSDL format (why i did not continue with your otherwise excellent link).Deanery
Try renaming your binding from WebHttpBinding to WebHttpBindingConfiguration and then updating your endpoint to use the new name. See also step 3 here: msdn.microsoft.com/en-us/library/ms733051.aspx . I don't know if that will fix the problem, but it's certainly giving me a headache to look at. :)Hobble
I found the issue; after some heavily research and no good answers on the net, I rethought the implementation in regards to the WebServiceHostFactory. Since this can be used WITHOUT the ServiceModel config entry, I doubt it ever reads from it. So I changed the implementation, and will document this in this thread so others as frustrated as me, can find a quick fix. Thanks for your help though :-)Deanery

© 2022 - 2024 — McMap. All rights reserved.