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

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

Rate This
  • Comments 2

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 http://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="http://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.

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) - http://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.

Blog - Comment List MSDN TechNet
  • Loading...
Leave a Comment
  • Please add 1 and 3 and type the answer here:
  • Post