Why can't I retrieve metadata of WCF service to generate proxy class successfully?

 

Symptom:

When we use svcutil.exe to generate the proxy class or configuration file through retrieving published WCF service metadata, or we add service reference in IDE to reference to a WCF service, we may receive below error message.

“There is an error in the XML document.
The maximum nametable character count quota (16384) 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.
If the service is defined in the current solution, try building the solution and adding the service reference again”

For example, suppose you have published a WCF service endpoint with net.tcp binding which metadata endpoint is deployed as follows:
net.tcp://WCFServer:88/yourService/MEX/

Then you use svcutil.exe to generate the proxy class and configuration file as follows:
Svcutil.exe net.tcp://WCFServer:88/yourService/mex/ /config:app.config /out:proxyclass.cs

You may receive above error message.

Root Cause & Solution:
When WCF client retrieves the large service metadata to generate client proxy class, the threashold about MaxNameTableCharCount of XmlDictionaryReaderQuotas object which is 16384 bytes is trigged when processing the large metadata XML file, just as described in the error message.

In order to customize this threshold, we need to configure a configuration file manually to reset value of MaxNameTableCharCount for the WCF metadata retrieving tool, such as svcuti.exe, or IDE. That is to say,
a) For svcutil.exe, we need to create a corresponding configuration file called svcutil.exe.config ;

 b) For Visual Studio2008, we need to create a corresponding configuration called devenv.exe.config.

Then add correct configuration section to the corresponding file and restart the tool.

a)  if your MEX endpoint is published with net.tcp binding, we could configure the endpoint with net.tcp binding as follows:

<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <system.serviceModel>

    <client>

      <endpoint name="net.tcp" binding="netTcpBinding" bindingConfiguration="bc" contract="IMetadataExchange" />

    </client>

    <bindings>

      <netTcpBinding>

        <binding name="bc" maxReceivedMessageSize="512000">

          <readerQuotas maxNameTableCharCount="2147483647" />

          <security mode="None"/>

        </binding>

      </netTcpBinding>

    </bindings>

  </system.serviceModel>

</configuration>

b) if your MEX endpoint is published with HTTP related binding, we could configure the endpoint with custom binding as follows:

<?xml version="1.0" encoding="utf-8"?>

<configuration>

  <system.serviceModel>

    <bindings>

      <customBinding>

        <binding name="MyBinding">

          <textMessageEncoding>

            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"

                maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

          </textMessageEncoding>

          <httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />

        </binding>

      </customBinding>

    </bindings>

    <client>

      <endpoint binding="customBinding" bindingConfiguration="MyBinding"

          contract="IMetadataExchange"

          name="http" />

    </client>

  </system.serviceModel>

</configuration>

References:
XmlDictionaryReaderQuotas
https://msdn.microsoft.com/en-us/library/aa702595.aspx

<readerQuotas>
https://msdn.microsoft.com/en-us/library/ms731325.aspx

Best Regards,

Winston He.