1

我有一个 WCF 服务(基于 SOAP)在调用某些 Web 方法时开始遇到以下异常:

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

虽然我们已经通过增加服务和客户端配置中的配额来解决此问题,但在我们开始遇到问题之前和应用配额增加之后,我发现消息响应没有任何差异。

我的问题是:

  1. 名称表是如何工作的?拥有最大值的名称表意味着什么?

  2. 有没有什么东西可以解释为什么我们在不改变服务和测试用例的情况下开始遇到这个异常?虽然我们添加了一些方法,但我不确定这是否是一个很好的解释,因为这些 Web 方法没有被调用。

  3. 关于调试名称表的任何建议并查看导致溢出的原因?

谢谢

4

2 回答 2

1
  1. 解析 xml 时,消息中的每个元素/属性名称都放在某个表中,因此可以有效地重用它们。这个配额的原因是为了避免dos(拒绝服务攻击),例如有人发送非常大的消息来消耗你所有的服务器处理代码。如果您不希望发生这种情况,您可以使用最大值。

  2. 也许您更改了 wcf 版本,因此默认值已更改。也可能某些原因导致客户端以不同的方式进行序列化(例如更多属性),因此它发送了更详细的内容。

  3. 只是增加配额并忘记它..你不想调试这个

于 2012-05-22T11:58:20.240 回答
1

虽然我们添加了一些方法,但我不确定这是否是一个很好的解释,因为这些 Web 方法没有被调用。

我在我们的 WCF 应用程序中看到了类似的行为,我们只是在协议中的一个 XML 消息中添加了一些属性。事实证明,这些新属性有点长(每个约 25 个字符),通过减少它们的长度,问题就消失了。

鉴于问题出现在我们的打开会话消息很小并且错误堆栈显示自动生成的 XML 序列化程序我得出结论,作为优化步骤,自动生成的 XML 序列化程序会尝试预先填充 XML 解析器的名称表第一次使用而不更改其默认最大大小 16Kb 以根据“已编译”XML 模式匹配实际大小。这就解释了为什么当 WCF 堆栈尝试反序列化一个微小的 XML 请求时会失败。

添加此行解决了上述问题:

webHttpBinding.ReaderQuotas.MaxNameTableCharCount = 32768;
于 2013-12-29T22:38:43.950 回答