none
Sending large strings to a WCF web service

    Question

  • We are developing a web service using WCF. One of the methods accepts XML to update a user's profile. Depending on the list of user's rights, the XML may become large - about 9kb. When this happens, I get an error saying that I have exceeded a quota of 8192 bytes. I understand that this is the defaut size and this number appears in the app.config of the client as the "maxStringContentLength" in the "readerQuotas" section. However, changing it to accommodate the larger string has no effect. Even if I change all occurrances of "8192" to "16384" in all files, the error still reports 8192 as the quota.

    What I do not understand, is that the error reports that the problem occurs during DEserialisatrion while READING the XML. This suggests that the problem is service-side (not client-side), but the CLIENT's app.config contains the "maxStringContentLength" in the "readerQuotas" section. Even inserting the section into the service's config, does not solve the problem. Also, setting a breakpoint in the service's code, shows that the error occurs before entering the service's method.

    I would really appreciate some help with this as I am not making any progress

    PS. We're using VS 2008 with .Net 3.5 on WinXP SP2.

    Friday, March 14, 2008 4:46 AM

Answers

  • If it is server side,  you should put a pointer to bindingConfiguration from <Service> tag 

            <services>
                <service name="Service" behaviorConfiguration="Servioce">
                    <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService11" contract="IMath" />
                </service>
            </services>

    Friday, March 21, 2008 8:39 PM
  • Thank you . That was the part I missed.

    The endpoint requires an address, binding and a contract at a minimum. I declared the named binding (in the service's web.config) with the modified <readerQuotas>, but neglected to spec the modified binding in the endpoint using the bindingConfiguration attribute. As soon as I did that, everything worked as advertised.

            <bindings>
                <basicHttpBinding>
                    <binding name="LargeBuffer"
    ...
                        <readerQuotas
                            maxDepth="2147483647"
                            maxStringContentLength="2147483647"
                            maxArrayLength="2147483647"
                            maxBytesPerRead="2147483647"
                            maxNameTableCharCount="2147483647" />
    ....
                    </binding>
                </basicHttpBinding>
            </bindings>
            <services>
                <service name="WcfService4.Service1" behaviorConfiguration="WcfService4.Service1Behavior">
                    <endpoint
                        bindingConfiguration="LargeBuffer" <!-- without this, the default quota of 8192 applies -->
                        address=""
                        binding="basicHttpBinding"
                        contract="WcfService4.IService1">
    ....
                    </endpoint>
                    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
                </service>
            </services>

    Wednesday, April 02, 2008 11:27 AM

All replies

  • What do you have your quotas set to on the server side?  The client is sending it to the server and the server is rejecting it.  So these setting must be turned up on the server (and should be on teh client too).  It never makes it into the method because wcf itself when it looks at the message will throw an exception before it ever gets to the method.

     

    http://www.danrigsby.com/blog/index.php/2008/02/20/how-to-throttle-a-wcf-service-help-prevent-dos-attacks-and-maintain-wcf-scalability/

     

    Should be at least this:

    <readerQuotas
                    maxDepth="64"

                    maxStringContentLength="2147483647"
                    maxArrayLength="2147483647"
                    maxBytesPerRead="4096"
                    maxNameTableCharCount="16384"/>

     

    If you need to send really BIG strings, look at implementing streaming channels.

     

    Friday, March 14, 2008 11:22 AM
  • The length of the string is about 8900 bytes; ie. slightly more than the (default) quota. I don't expect it to ever be much more than that.

    I copied your settings to the client config. I then copied the entire <bindings> section from the client's config to the service's config and rebuilt the solution.

    The error still occurs and it still reports 8192 as the quota.

    Here is the the snippet from the config:

        <system.serviceModel>
            <bindings>
                <wsHttpBinding>
                    <binding name="WSHttpBinding_IService11" closeTimeout="00:01:00"
                        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                        allowCookies="false">
                        <readerQuotas
                            maxDepth="64"
                            maxStringContentLength="2147483647"
                            maxArrayLength="2147483647"
                            maxBytesPerRead="4096"
                            maxNameTableCharCount="16384"/>
                        <reliableSession ordered="true" inactivityTimeout="00:10:00"
                            enabled="false" />
                        <security mode="Message">
                            <transport clientCredentialType="Windows" proxyCredentialType="None"
                                realm="" />
                            <message clientCredentialType="Windows" negotiateServiceCredential="true"
                                algorithmSuite="Default" establishSecurityContext="true" />
                        </security>
                    </binding>
                </wsHttpBinding>
            </bindings>
            <client>
                <endpoint address="http://localhost:2306/Service1.svc" binding="wsHttpBinding"
                    bindingConfiguration="WSHttpBinding_IService11" contract="ServiceReference1.IService1"
                    name="WSHttpBinding_IService11">
                    <identity>
                        <dns value="localhost" />
                    </identity>
                </endpoint>
            </client>
        </system.serviceModel>

    Friday, March 14, 2008 11:45 AM
  • If it is server side,  you should put a pointer to bindingConfiguration from <Service> tag 

            <services>
                <service name="Service" behaviorConfiguration="Servioce">
                    <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService11" contract="IMath" />
                </service>
            </services>

    Friday, March 21, 2008 8:39 PM
  • Thank you . That was the part I missed.

    The endpoint requires an address, binding and a contract at a minimum. I declared the named binding (in the service's web.config) with the modified <readerQuotas>, but neglected to spec the modified binding in the endpoint using the bindingConfiguration attribute. As soon as I did that, everything worked as advertised.

            <bindings>
                <basicHttpBinding>
                    <binding name="LargeBuffer"
    ...
                        <readerQuotas
                            maxDepth="2147483647"
                            maxStringContentLength="2147483647"
                            maxArrayLength="2147483647"
                            maxBytesPerRead="2147483647"
                            maxNameTableCharCount="2147483647" />
    ....
                    </binding>
                </basicHttpBinding>
            </bindings>
            <services>
                <service name="WcfService4.Service1" behaviorConfiguration="WcfService4.Service1Behavior">
                    <endpoint
                        bindingConfiguration="LargeBuffer" <!-- without this, the default quota of 8192 applies -->
                        address=""
                        binding="basicHttpBinding"
                        contract="WcfService4.IService1">
    ....
                    </endpoint>
                    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
                </service>
            </services>

    Wednesday, April 02, 2008 11:27 AM
  • Stoffel,

     

    Thank you so much for you post. I was facing the same problem.

     

    Regards,

    Igor Santana

    Thursday, July 17, 2008 1:19 PM
  • Thanks for the posts. I am facing the same issue.

    One thing I don't understand though: If I change identity of application pool from a domain account to "Network Service" account , I don't see this error.

     

    Friday, September 12, 2008 2:51 AM
  • Great man. After finding a lot, I found this page link.
    And fixed my problem.

    Thanks very much.
    Monday, July 06, 2009 6:26 AM