Too many operations or methods in WCF Service causes the metaDataExchange fail

Symptom: Too many methods or operations in WCF service hosted on net.tcp or http binding might lead svcutil.exe to throw the below exception while creating a proxy.

Cannot obtain Metadata from net.tcp://localhost:8090/MyService/Mex If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.  For help enabling metadata publishing, please refer to the MSDN documentation at https://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error    URI: net.tcp://localhost:8090/MyService/Mex    Metadata contains a reference that cannot be resolved: 'net.tcp://localhost:809/MyService/Mex'.    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.

Cause: Provided metadataExchange on mexTCPBinding or mexHttpBinding and maximum nametable character count (one of the attributes in readerQuotas) qutoa is set to conservative value by default with no provision to manipulate.

Solution: Create a new mex endpoint in the svcUtil.exe.config that matches the mex endpoint on the service and configure the quotas on this new endpoint. This new endpoint should not be a mex binding but a regular binding, since mex binding does not facilitate changing readerQuota values.

Note: svcutil.exe.config does not exist by default, you will have to create it.

Here's a solution for a service with two metadataExchange endpoints. One is net.Tcp binding with no security and the other one is wsHttp binding with Message level security.

Partial Service Configuration file:

    <bindings>
      <netTcpBinding>
        <binding name="GenericBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
             maxReceivedMessageSize="2147483647" >
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
             maxArrayLength="2147483647" maxBytesPerRead="2147483647"
             maxNameTableCharCount="2147483647" />
          <security mode="None"/>
        </binding>
      </netTcpBinding>
      <wsHttpBinding>
        <binding name="SecureBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
             maxReceivedMessageSize="2147483647" >
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
             maxArrayLength="2147483647" maxBytesPerRead="2147483647"
             maxNameTableCharCount="2147483647" />
          <security mode="Message">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

    <services>
      <service behaviorConfiguration="MyService.NetTcpService" name="MyService.NetTcpService">
        <endpoint address="mex" name="net.tcp" binding="netTcpBinding" bindingConfiguration="GenericBinding"
        contract="IMetadataExchange" />
        <endpoint address="NetTcpService" binding="netTcpBinding" bindingConfiguration="GenericBinding" name="TCPEndpoint"
          contract="MyService.INetTcpService" />
        <host>
          <baseAddresses>
               <add baseAddress="net.tcp://localhost/MyService" />
          </baseAddresses>
        </host>
      </service>
      <service
        behaviorConfiguration="MyService.WsHttpService" name="MyService.WsHttpService">
        <endpoint address="mex" name="http" binding="wsHttpBinding" bindingConfiguration="SecureBinding" contract="IMetadataExchange"/>
        <endpoint address="WsHttpService" binding="wsHttpBinding" bindingConfiguration="SecureBinding" name="httpEndpoint"
          contract="MyService.IWsHttpService" />
        <host>
          <baseAddresses>                         
            <add baseAddress="https://localhost:8095/MyService" />
          </baseAddresses>
        </host>
      </service>
    <services>

Svcutil.exe.config:

    <configuration>
      <system.serviceModel>
       <client>
          <endpoint name="net.tcp" binding="netTcpBinding" bindingConfiguration="GenericBinding"
              contract="IMetadataExchange" />
          <endpoint name="http" binding="wsHttpBinding" bindingConfiguration="SecureBinding" contract="IMetadataExchange" />
       </client>
       <bindings>
        <netTcpBinding>
          <binding name="GenericBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
             maxReceivedMessageSize="2147483647" >
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
             maxArrayLength="2147483647" maxBytesPerRead="2147483647"
             maxNameTableCharCount="2147483647" />
            <security mode="None"/>
          </binding>
        </netTcpBinding>
        <wsHttpBinding>
          <binding name="SecureBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
             maxReceivedMessageSize="2147483647" >
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
             maxArrayLength="2147483647" maxBytesPerRead="2147483647"
             maxNameTableCharCount="2147483647" />
            <security mode="Message">
              <transport clientCredentialType="Windows" />
            </security>
          </binding>
        </wsHttpBinding>
      </bindings>
     </system.serviceModel>
   </configuration>

Note: The name of the mex endpoint is very important, as svcutil.exe goes with the name attribute along with binding attribute to identify the type of binding being used. As you can see above, i've use net.tcp and http for NetTcpBinding and WsHttpBinding respectively.
For Visual Studio 2010 we also need to add the same updated svcutil.exe file in another location under: “C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools” which is a new folder under VS 2010 Microsoft SDKs which also has an svcutil.exe application.

Here’s the sample that explains ‘configuring svcutil to use a non-default binding for metadata exchange’ technique (in the context of a service with a secure mex binding) - https://msdn2.microsoft.com/en-us/library/aa395212.aspx 

If you want to use Visual Studio's ‘Add Service Reference’ you will need to make the changes the machine.config file or devenv.exe.config.

Comments

  • Anonymous
    June 11, 2009
    One of the most important parts is the last sentence. And note that there are two possible config files you may need to  change. devenv.exe.config  VS config file for adding a service reference in VS svcUtil.exe.config  config file for wcf test client Thanks for the help Zafar.

  • Anonymous
    November 08, 2009
    Thanks guys, you saved me.. i almost spent 18 hrs to figure this out..

  • Anonymous
    November 16, 2009
    If i change the svcutil.exe.config and devenv.exe.config file for the service with too many operations/methods works fine, where as for other wcf services which uses <endpoint address="mex" binding="mexTcpBinding" /> fails. Thank you Lakshmi

  • Anonymous
    November 20, 2009
    The error message: 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 I ran into this problem when my WCF service reached a large size.   I could no longer right click on the service in Visual Studio and select Update service reference.   I also could not run svcutil.exe without an error when my WCF service was large. When I commented out some of the functions to get the size smaller, everything would work, but when I added even one function after that point, it would fail.   No matter what the function was. I found out which files needed to be changed by using process monitor while doing various operations. To fix these problems I had to do 5 things:

  1. Replace the svcutil.exe.config file with: My file was located here: SvcUtil.exe.config <?xml version="1.0" encoding="utf-8"?> <configuration>   <system.serviceModel>       <client>          <endpoint name="net.tcp" binding="netTcpBinding" bindingConfiguration="GenericBinding"              contract="IMetadataExchange" />          <endpoint name="http" binding="wsHttpBinding" bindingConfiguration="SecureBinding" contract="IMetadataExchange" />       </client>       <bindings>        <netTcpBinding>          <binding name="GenericBinding" maxBufferPoolSize="2147483647"             maxReceivedMessageSize="2147483647" >            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"             maxArrayLength="2147483647" maxBytesPerRead="2147483647"             maxNameTableCharCount="2147483647" />            <security mode="None"/>          </binding>        </netTcpBinding>        <wsHttpBinding>          <binding name="SecureBinding" maxBufferPoolSize="2147483647"             maxReceivedMessageSize="2147483647" >            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"             maxArrayLength="2147483647" maxBytesPerRead="2147483647"             maxNameTableCharCount="2147483647" />            <security mode="Message">              <transport clientCredentialType="Windows" />            </security>          </binding>        </wsHttpBinding>      </bindings>     </system.serviceModel> </configuration>
  2. Add the client endpoints and the <bindings> element to your machine.config. My file was located here: C:WindowsMicrosoft.NETFrameworkv2.0.50727CONFIGmachine.config
  3. Add the whole <System.ServiceModel> inside your devenv.exe.config My file was located here: C:Program FilesMicrosoft Visual Studio 9.0Common7IDEdevenv.exe.config
  4. Modify the endpoint and bindings of my client app. (myapp.exe.config)
  5. Modify the endpoints and bindings of my WCF service. (mywcfservice.exe.config)