Today I was taught an immensely important lesson by WCF. It actually has nothing

to do with WCF except that because of the size of the schema I’m working with that

is where I encountered it.

I do a lot of work in the healthcare industry, and that industry, by government mandate,

works with a message format called the 837 (properly the X12 4010A1 837 either I,

P or D). The 837 has three flavors, and is absolutely huge. I was crafting

a service which had to accept an XML representation of this data. How did I create

the XML? BizTalk Server 2006 R2’s new HIPAA support of course. When

I made the call to service from my unit tests I first received a Fault indicating

that exception details could not be returned because of configuration. No problem,

obviously I’ve seen this before and so I added the following to my app.Config for

the Host executable:


              <

              behaviors

              >

            

              <

              serviceBehaviors

              >

            

              <

              behavior

              name

              ="EnableDebugging"

              >

            

              <

              serviceDebug

              includeExceptionDetailInFaults

              ="true"

              />

            

              </

              behavior

              >

            

              </

              serviceBehaviors

              >

            

              </

              behaviors

              >

            

Now that I’ve enabled debugging, surely now I’ll see some sort of clear reason by

this occurred. Nope! I was presented with the following:

TheCompany.Services.Tests.ClaimsService.GetListOfClaimsByStatus : System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]

: Error in deserializing body of request message for operation ‘GetClaimListByStatus’.

Well isn’t that terribly useful. Fortunately, this did give me the single most

important piece of information “deserializing”. So off I go to Google my brain,

because I’d

written a post before on how to debug the XmlSerializer (and I was using the XmlSerializer

in this case because the DataContractSerializer could not work with my schema).

As that post will tell you, there is a switch that can be set in the app.Config which

will enable you to debug the code generated by the XmlSerializer. So now we

add the following to my app.Config:


              <

              system.diagnostics

              >

            

              <

              switches

              >

            

              <

              add

              name

              ="XmlSerialization.Compilation"

              value

              ="1"

              />

            

              </

              switches

              >

            

              </

              system.diagnostics

              >

            

And we follow that by running the unit tests again, that results in something that

is actively useful:

For those reading along at home and wanting the full text that says:

The maximum nametable character count quota (10000) has been exceeded while reading

XML data. The nametable is a data structure used to store strings encountered during

XML processing – long XML documents with non-repeating element names, attribute names

and attribute values may trigger this quota. This quota may be increased by changing

the MaxNameTableCharCount property on the XmlDictionaryReaderQuotas object used when

creating the XML reader.

Now that is useful, it tells me exactly how to correct the problem and the size of

the quota currently. The only problem is that I didn’t create this XmlReader

object, I didn’t even create the XmlSerializer which created this XmlReader.

The only thing which I create was a ServiceHost, how can I change that setting?

Enter Google again.

As it happens, Windows Communication Foundation does include an ability to override

that value, it is stored in the Binding Configuration in your … you guessed it …

app.Config! Add the following snippet (assuming you’re using Basic Http Binding

(it exists for all bindings though) and you’ll be good to go:


              <

              bindings

              >

            

              <

              basicHttpBinding

              >

            

              <

              binding

              name

              ="BasicHttpBinding"

              >

            

              <

              readerQuotas

              maxNameTableCharCount

              ="100000"

              />

            

              </

              binding

              >

            

              </

              basicHttpBinding

              >

            

              </

              bindings

              >

            

Now, surely I’m done, and things will work. Actually, no it took mea few

times to find a value that would work for that quota. Once I did though I finally

hit my breakpoint inside the service and was able to send back a response, where upon

I got this message:

TheCompany.Services.Tests.ClaimsService.GetListOfClaimsByStatus : System.ServiceModel.CommunicationException

: Error in deserializing body of reply message for operation ‘GetClaimListByStatus’.

—-> System.InvalidOperationException : There is an error in XML document

(1, 252).

—-> System.Xml.XmlException : The maximum nametable character count quota

(10000) has been exceeded while reading XML data. The nametable is a data structure

used to store strings encountered during XML processing – long XML documents with

non-repeating element names, attribute names and attribute values may trigger this

quota. This quota may be increased by changing the MaxNameTableCharCount property

on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 1,

position 252.

At least when the error occurs on the client side you get the full details to start

with! Make the same modification above to your configuration on the client side

and you’re good to go.