1

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>
John Saunders
  • 160,644
  • 26
  • 247
  • 397
deadcom
  • 13
  • 1
  • 1
  • 3

2 Answers2

4

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

Richard Blewett
  • 6,089
  • 1
  • 18
  • 23
  • 2
    I managed to figure out the problem - I simply took out the binding name on the server config ( – deadcom Aug 16 '11 at 18:38
  • I still have the service name specified as FlightTicketWebService, which works despite not being the fully-qualified name. – deadcom Aug 16 '11 at 18:44
  • Well it amounts to same same thing as what you have done is change the default binding configuration (that's what using no name does). Your service element and the endpoint you have specified are being ignored. The default for an http based base address is to use BasicHttpBinding which is why you are seeing your behavior – Richard Blewett Aug 16 '11 at 18:44
  • I have been battling this error for 3 weeks now (off and on)... what a relief. Though, I think this WCF stuff could be made a bit easier or have better documentation! – deadcom Aug 16 '11 at 18:46
  • Thanks for your help. Though, I definitely had the service specified with a fully-qualified name in the many iterations of the config I generated while trying to solve this issue. Strange that it never seemed to work for me. – deadcom Aug 16 '11 at 18:48
2

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>
Alex Fairchild
  • 1,025
  • 11
  • 11