已超出最大可命名字符数配额 (16384)

Posted

技术标签:

【中文标题】已超出最大可命名字符数配额 (16384)【英文标题】:The maximum nametable character count quota (16384) has been exceeded 【发布时间】:2013-08-16 16:17:34 【问题描述】:

我刚刚增加了我的 ServiceContract 中的方法数量。当我在 Visual Studio 中更新服务参考时,我收到消息:

元数据包含无法解析的引用: 'net.tcp://xxxxx.com:8002/DataQueryService/mex'。

XML 文档中有错误。

最大可命名字符 读取 XML 数据时已超出计数配额 (16384)。这 nametable 是一种数据结构,用于存储过程中遇到的字符串 XML 处理 - 具有非重复元素名称的长 XML 文档, 属性名称和属性值可能会触发此配额。这 可以通过更改 MaxNameTableCharCount 属性来增加配额 在创建 XML 时使用的 XmlDictionaryReaderQuotas 对象上 阅读器。

原来的服务器端配置是:

 <services>
      <service behaviorConfiguration="XXXXX.DataQueryService.ServiceBehavior" name="XXXXX.DataQueryService.QueryService">
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://xxxxx.com:8002/DataQueryService" />
          </baseAddresses>
        </host>
        <endpoint name="MexEndpoint" address="mex" binding="customBinding" bindingConfiguration="unsecureTcpMex" contract="IMetadataExchange" />
    </service>
</services>

<bindings>
    <customBinding>
        <binding name="unsecureTcpMex">
            <tcpTransport portSharingEnabled="True" />
        </binding>
    </customBinding>    
</bindings>

我修改为:

<bindings>
    <customBinding>
        <binding name="unsecureTcpMex">
            <textMessageEncoding>
                <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
            </textMessageEncoding>
            <tcpTransport portSharingEnabled="True" maxReceivedMessageSize="2147483647"  />
        </binding>
    </customBinding>    
</bindings>

我需要对我的配置进行哪些其他更改才能使其正常工作?

更新 按照@Chris 的建议,我尝试更新 SVCUtil 的配置文件。我向我的端点添加了一个名称,以便它匹配(上面更新)。 SvcUtil.config 现在如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <system.serviceModel>
        <bindings>
            <customBinding>
                <binding name="unsecureTcpMex">
                    <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="unsecureTcpMex"
                contract="IMetadataExchange"
                name="MexEndpoint" />
        </client>
    </system.serviceModel>
</configuration>

【问题讨论】:

也许您的消息太大或由太多 xml 元素/属性组成? 增加的是操作合约的数量。这导致了问题。 您使用的是哪个版本的 WCF(双方)? 【参考方案1】:
<binding name="NameSoap" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" messageEncoding="Text">
    <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="1638400" />
    <security mode="None">
        <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
        <message clientCredentialType="UserName" algorithmSuite="Default" />
    </security>
</binding>

看看这一行:ma​​xNameTableCharCount="1638400"

【讨论】:

谢谢 Bart,但我已经将该值从默认值 16384 增加到整数的最大值 - 2147483647。【参考方案2】:

我认为将操作拆分为多个合同不切实际?介意我问一下我们在谈论多少服务操作?

您尝试过这篇文章中的解决方案吗? http://social.msdn.microsoft.com/Forums/vstudio/en-US/17592561-c470-452a-a52c-2a5a2839582c/metadataexchangeclient-and-nametable-character-count-quota

其他建议包括使用 Discovery 协议来读取元数据,该协议没有任何读取器配额: http://msdn2.microsoft.com/en-us/library/system.web.services.discovery.discoveryclientprotocol.aspx

底部的解决方案建议您在启动服务之前更改代码中的默认阅读器配额。我相信这必须在自定义 ServiceHost 工厂中完成。如果您愿意提供帮助,请告诉我。

希望这会有所帮助。

【讨论】:

谢谢,我已经看过你提供的第一个链接。我们的解决方案可能已经太成熟,无法按照建议更改发现方法。我已经看到其他人已经成功更改了 readerQuotas,所以我也想这样做。这意味着只需对配置文件进行几行更改。当您说“在自定义 ServiceHost 工厂中”时,这是什么意思?是不是不能在配置文件里做? 这个页面描述了如何创建一个自定义服务主机来对你的服务进行一些自定义配置,除了阅读配置文件,包括如何使用 IIS。 msdn.microsoft.com/en-us/library/aa395224.aspx 这将允许您在创建服务之前设置读者配额,我认为这是您问题的根源,以及为什么不能单独在配置文件中完成。祝你好运! 我认为 SvcUtil.exe 和 Visual Studios 服务引用仍然无法与此解决方案一起使用是否正确。我们的构建过程是自动化的,实际上也是构建失败了,所以我需要找到一个可以修改配置文件的解决方案。许多其他人通过修改客户端配置文件成功地克服了这个问题。我只是想找出我的配置文件中有哪些错误。 我想指出,在第一个链接的页面底部有一些代码为我解决了这个问题。我正在使用 IIS6,并且不得不使用反射来增加 System.ServiceModel 中 ReaderQuotas 中的 MaxNameTableCharCount。我无法在配置中修复,谢谢。【参考方案3】:

这应该会有所帮助: http://geekswithblogs.net/claraoscura/archive/2007/08/20/114806.aspx 看来解决方案是为 svcutil 创建一个配置文件并将其放在与它相同的文件夹中。

【讨论】:

谢谢。我为上面详述的 SvcUtil.exe 添加了一个配置文件。但是我仍然遇到同样的错误。只是我需要更改的 SvcUtil 文件还是服务器端的文件? 您应该只更改消费应用程序 好的,我尝试修改 SvcUtil 的配置文件(如上),但仍然无法正常工作。【参考方案4】:

尝试以编程方式为 MaxNameTableCharCount 属性设置新值:

Binding binding = endpoint.Binding;

XmlDictionaryReaderQuotas myReaderQuotas = new XmlDictionaryReaderQuotas();
myReaderQuotas.MaxStringContentLength = something;
myReaderQuotas.MaxArrayLength = something;
myReaderQuotas.MaxBytesPerRead = something;
myReaderQuotas.MaxDepth = something;
myReaderQuotas.MaxNameTableCharCount = something;

binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null);

注意:您必须在创建客户端代理和/或服务主机之前进行设置。一旦创建,就无法更改。

【讨论】:

我们的构建过程是自动化的,实际上也是构建失败了,所以我需要找到一个可以修改配置文件的解决方案。许多其他人通过修改客户端配置文件成功地克服了这个问题。我只是想找出我的配置文件中有哪些错误。 您的错误消息是否仍然显示:“最大可命名字符计数配额 (16384)”。我说要试试这个,因为它看起来不像是在读取你的新值(16384 而不是你的 2147483647)。一旦我遇到类似的问题,但从配置文件中更改它不起作用,但它在运行时起作用。 是的,错误信息还是一样的。我们的构建脚本的设置方式我需要在配置文件中指定值。通过更改配置,它适用于其他用户。有什么理由不适合我吗?

以上是关于已超出最大可命名字符数配额 (16384)的主要内容,如果未能解决你的问题,请参考以下文章

已超出传入邮件的最大邮件大小配额 (65536)

已超出传入邮件的最大邮件大小配额 (65536)

WCF,已超出传入邮件的最大邮件大小配额 (65536)

WCF MaxReceivedMessageSize:超出最大邮件大小配额

Web Service 或 WCF调用时读取 XML 数据时,超出最大字符串内容长度配额(8192)解决方法

服务“gmail.googleapis.com”的配额指标“查询”和限制“每个用户每分钟的查询数”超出配额