我有一个WCF服务(基于SOAP),在调用某些Web方法时开始遇到以下异常:
System.Xml.XmlException:读取XML数据时已超出最大名称字符集计数配额(16384)。 nametable是用于存储XML处理期间遇到的字符串的数据结构 - 具有非重复元素名称,属性名称和属性值的长XML文档可能会触发此配额。通过更改创建XML阅读器时使用的XmlDictionaryReaderQuotas对象上的MaxNameTableCharCount属性,可以增加此配额。第1行,第4221位。 在System.Xml.XmlExceptionHelper.ThrowXmlException
虽然我们已经通过增加服务和客户端配置中的配额来修复此问题,但在我们开始遇到问题之前和应用配额增加之后,我发现消息响应没有差异。
我的问题是:
名称表如何真正起作用?使名称表具有最大值会产生什么影响?
是否有可能解释为什么我们在不更改服务和测试用例的情况下开始遇到此异常的原因?我们添加了几种方法但是我不确定这是否是一个很好的解释,因为这些Web方法没有被调用。
有关调试名称表的任何建议,看看导致溢出的原因是什么?
由于
答案 0 :(得分:1)
在解析xml时,消息中的每个元素/属性名称都放在某个表中,因此可以有效地重用它们。这个配额的原因是为了避免dos(拒绝服务攻击),例如:有人发送非常大的消息来使用您的所有服务器处理代码。如果您不希望发生这种情况,可以使用最大值
也许您更改了wcf版本,因此默认值已更改。也许某些事情导致客户端以不同的方式进行序列化(例如更多属性),因此它发送了更冗长的内容。
只是增加配额而忘了它..你不想调试这个
答案 1 :(得分:1)
我们添加了几种方法但是我不确定这是否是一个很好的解释,因为这些Web方法没有被调用。
在我们的WCF应用程序发生更改之后,我看到了类似的行为,我们只是在协议中的一条XML消息中添加了一些属性。事实证明,这些新属性很少(每个约25个字符),并且通过减少它们的长度,问题就消失了。
鉴于问题出现在我们的开放会话消息很小并且错误堆栈显示自动生成的XML序列化程序我得出结论,作为优化步骤,自动生成的XML序列化程序尝试预先填充XML首次使用时,解析器的名称表不会根据“已编译的”XML架构更改其默认最大大小16Kb以匹配实际大小。这就解释了为什么当WCF堆栈尝试反序列化时,一个微小的XML请求就会崩溃。
添加此行解决了上述问题:
webHttpBinding.ReaderQuotas.MaxNameTableCharCount = 32768;