Sending object to WCF service. MaxStringContentLength (8192 bytes) exceeded when deserializing

13.1k views Asked by At

I created a simple WCF web service that has one method: SubmitTicket(flightticket ft, string username, string password)

On the client side, I have an application for filling out a form (a flight ticket) and sending it to this newly created web service. When this flightticket object exceeds 8192bytes I get the following error:

"There was an error deserializing the object of type flightticket. The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader"

I did some research online and found that I have to set the MaxStringContentLength in the web.config (server) and app.config (client) to a higher number. Problem is, I've tried every possible combination of settings in both config files from reading various blogs and sites, but it STILL fails on that same error!

I have attached my client and server config code (as it is at the moment, it has gone through many many many changes over the day with no success).

One thing I noticed is that the configuration.svcinfo file on my client application seems to always shows 8192 for MaxStringContentLength when I update the service reference. It appears to take all the default values even if I explicitly set the binding properties. Not sure if that is related to my problem at all, but worth mentioning.


Here is the applicable app.config/web.config code for defining the endpoint bindings:

<<<<< CLIENT >>>>>

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IFlightTicketWebService" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                useDefaultWebProxy="true">
                <readerQuotas maxDepth="32" maxStringContentLength="65536" maxArrayLength="16384"
                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                <security mode="None">
                    <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
                    <message clientCredentialType="UserName" algorithmSuite="Default" />
                </security>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://xx.xx.xx/xxxxxxxx.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFlightTicketWebService"
            contract="FlightTicketWebService.IFlightTicketWebService"
            name="BasicHttpBinding_IFlightTicketWebService" />
    </client>
</system.serviceModel>
</configuration>

<<<<< SERVER >>>>>

<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
  <section name="GSH.FlightTicketWebService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web>
<httpRuntime maxRequestLength="16384"/>
<compilation debug="true" targetFramework="4.0"/>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>

<system.serviceModel>
  <bindings>
      <basicHttpBinding>
          <binding name="BasicHttpBinding_IFlightTicketWebService" closeTimeout="00:01:00"
              openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
              allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
              maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
              messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
              useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="65536" maxArrayLength="16384"
                  maxBytesPerRead="4096" maxNameTableCharCount="16384" />
              <security mode="None">
                  <transport clientCredentialType="None" proxyCredentialType="None"
                      realm="" />
                  <message clientCredentialType="UserName" algorithmSuite="Default" />
              </security>
          </binding>
      </basicHttpBinding>
  </bindings>
<behaviors>     
<serviceBehaviors>        
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<services>
    <service name="FlightTicketWebService">
        <endpoint 
            name="FlightTicketWebServiceBinding"
            address="http://xx.xx.xx/xxxxxxxxxxx.svc" 
            binding="basicHttpBinding" 
            bindingConfiguration="BasicHttpBinding_IFlightTicketWebService"
            contract="IFlightTicketWebService"/>
    </service>
</services>
</system.serviceModel>
<system.webServer>
2

There are 2 answers

5
Richard Blewett On BEST ANSWER

I think the problem is that your service is not picking up its config because you have set the service name to be FlightTicketWebService whereas I would guess that the actual type is in a namespace. Fully qualify the service name with the namespace and it should pick up your config

Essentially this is a by-product of the WCF 4 default endpoint functionality that if it finds no matching config it puts endpoints up with the default config

0
Alex Fairchild On

This is the answer! I have searched everywhere the solution to this problem in WCF 4.0, and this entry by Richard Blewett was the final piece of the puzzle.

Key things learned from my research:

  • if the exception is thrown by the service, then only change the Server Web.config file; don't worry about the client
  • create a custom basicHttpBinding:
<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="customBindingNameForLargeMessages">
  • add the larger readerQuota values (largest possible shown here, adjust to taste)
        <binding name="customBindingNameForLargeMessages"
          maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647"
             maxStringContentLength="2147483647"
             maxArrayLength="2147483647"
             maxBytesPerRead="2147483647"
             maxNameTableCharCount="2147483647" />
        </binding>
    </basicHttpBinding>
</bindings>
  • create a service entry, with an endpoint that maps to the custom binding. The mapping happens when the endpoint's bindingConfiguration is the same as the binding's name:
  • Make sure the service name and the contract value are fully qualified - use the namespace, and the name of the class.
<system.serviceModel>
    <services>
        <service name="Namespace.ServiceClassName">
             <endpoint 
                 address="http://urlOfYourService"
                 bindingConfiguration="customBindingNameForLargeMessages"                     
                 contract="Namespace.ServiceInterfaceName" 
                 binding="basicHttpBinding"
                 name="BasicHTTPEndpoint" />
        </service>
    </services>