WCF - 读取XML数据时,最大名称表字符计数配额(16384)已超过限制

9

我有一个使用wsHttpBinding的WCF服务。服务器配置如下:

<bindings>
      <wsHttpBinding>
        <binding name="wsHttpBinding" maxBufferPoolSize="2147483647"
          maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="None">
            <transport clientCredentialType="Windows" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="Windows" negotiateServiceCredential="true"
              algorithmSuite="Default" establishSecurityContext="true" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>

在客户端,我包含了WCF服务的Service引用。如果我的IService中有限定函数,比如90个Operation Contract,那么它的工作效果很好,但是如果我添加了一个以上的OperationContract,我就无法更新Service引用,也无法添加那个服务引用。在这篇文章中提到,通过更改那些配置文件(即devenv.exe.config、WcfTestClient.exe.config和SvcUtil.exe.config),它会起作用,但即使在这些配置文件中包括这些绑定,仍然会弹出错误,提示:

下载'http://10.0.3.112/MyService/Service1.svc/mex'时出错。 请求失败,HTTP状态码为400: 错误请求。 元数据包含无法解析的引用:'http://10.0.3.112/MyService/Service1.svc/mex'。 XML文档中存在错误(1, 89549)。 读取XML数据时已超过最大名称表字符计数配额(16384)。名称表是一种数据结构,用于存储在XML处理期间遇到的字符串 - 具有非重复元素名称、属性名称和属性值的长XML文档可能会触发此配额。可以通过更改创建XML阅读器时使用的XmlDictionaryReaderQuotas对象上的MaxNameTableCharCount属性来增加此配额。第1行,第89549个位置。 如果服务在当前解决方案中定义,请尝试构建解决方案并再次添加服务引用。

有什么解决方法吗????

4个回答

12
尝试以下步骤: 在你的Visual Studio安装目录中,即devenv.exe所在的位置(例如C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE),将以下部分添加到devenv.exe.config文件中。
<system.serviceModel>
<client>
  <endpoint binding="customBinding" bindingConfiguration="largeServiceBinding" contract="IMetadataExchange" name="http" />
</client>

<bindings>
  <customBinding>
    <!-- NOTE: The binding name must be the same as specified in the config file of the wcf service -->
    <binding name="largeServiceBinding" >
      <textMessageEncoding>
        <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      </textMessageEncoding>

      <httpTransport transferMode="Buffered" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
    </binding>

  </customBinding>
</bindings>
</system.serviceModel>

在您的WCF服务的app.config文件中添加相同的绑定:

<bindings>
  <customBinding >
    <!-- NOTE: The binding name must be the same as specified in the devenv.exe.config file located ..\Common7\IDE folder of the VS installation directory -->
    <binding name="largeServiceBinding" >
      <textMessageEncoding>
        <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647"
          maxNameTableCharCount="2147483647" />
      </textMessageEncoding>
      <httpTransport transferMode="Buffered" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
    </binding>
  </customBinding>
</bindings>

请注意,两个文件中绑定标签的名称属性必须匹配(例如largeServiceBinding)。

最后将以下mex端点添加到您的服务标记中:

 <endpoint address="mex" binding="customBinding" contract="IMetadataExchange" bindingName="testBinding" bindingConfiguration="largeServiceBinding" name="http"/>

这可能看起来像这样:

 <services>
  <service behaviorConfiguration="MyServiceBehavior"
    name="MyService.MyService">
    <endpoint address="" binding="wsHttpBinding" contract="MyService.IMyService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="customBinding" contract="IMetadataExchange" bindingName="testBinding" bindingConfiguration="largeServiceBinding" name="http"/>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8731/Design_Time_Addresses/MyService/MyService/" />
      </baseAddresses>
    </host>
  </service>
</services>

谢谢回复,我会尝试并告诉您结果。 - Jankhana
它起作用了,谢谢。在那之后,我不得不更改客户端中的服务端点设置,然后它就起作用了。谢谢!!! - Jankhana
这对我也起作用了,但是没有必要添加新的绑定,我只需使用上述方法更新readerQuotas即可。 - endyourif

5

我知道已经过了一段时间,但是我遇到了同样的问题,并找到了其他(更简单)的解决方案 在codeproject上

在那里提供的解决方案中,这些值是在代码中设置而不是在.config文件中设置的。

        BasicHttpBinding binding = new BasicHttpBinding();
        binding.Security.Mode = BasicHttpSecurityMode.Transport;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
        binding.MaxReceivedMessageSize = 50000000;
        binding.ReaderQuotas.MaxArrayLength = 50000000;
        binding.ReaderQuotas.MaxStringContentLength = 50000000;
        binding.ReaderQuotas.MaxNameTableCharCount = 50000000;
        EndpointAddress endpoint = new EndpointAddress(new Uri("https://server/EWS/Exchange.asmx"));
        ExchangeServicePortTypeClient ews = new ExchangeServicePortTypeClient(binding, endpoint);

然而,我在.config文件中更改了相关值(在<binding><readerQuotas>部分都更改),并解决了问题(而不是添加自定义绑定):

                <binding name="ITransactionProcessor" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="50000000" maxBufferPoolSize="524288" maxReceivedMessageSize="50000000"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="50000000" maxArrayLength="50000000"
                        maxBytesPerRead="4096" maxNameTableCharCount="50000000" />
                    <security mode="TransportWithMessageCredential">
                        <transport clientCredentialType="None" proxyCredentialType="None" 
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>

我希望这能对某些人有所帮助 :)

1
在你的 app.config 或 dll.config 文件中添加以下内容:
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="myMex" maxReceivedMessageSize="1024000"> <!-- modify this to avoid stupid error -->
<readerQuotas maxNameTableCharCount="163840" /> <!-- DO NOT touch this one -->
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>

...

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

...

        </client>
    </system.serviceModel>
</configuration>

就是这样! 这是WCF中真正令人讨厌的事情之一,而且经常会在谷歌上给你带来很多无用的信息。 我浪费了很多时间在这个问题上。


1
需要注意的一点是,该消息指的是svcutil读取配额而不是服务配额!Svcutil有一个限制,即它可以读取多少元数据。可以通过配置文件更改此限制。解决方案是为svcutil创建一个配置文件,并将其放置在与工具相同的文件夹中。下次运行svcutil时,将考虑配置文件值。

http://geekswithblogs.net/claraoscura/archive/2007/08/20/114806.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接