如何在.NET中调试反序列化错误?

22

.NET的反序列化错误非常通用,例如像这样的:

System.ArgumentException: 对象类型为 'System.Uri' 的对象无法转换为类型 'System.String'。

很明显我们改变了对象中某个属性的类型,但是在这个序列化对象中有10-15个不同的类,因此很难确定哪一个被更改或者哪次提交出了问题。

是否有任何方法可以获取哪个类中的哪个属性(或至少是哪个类)实际上导致了此错误?是否存在任何外部工具或已知的方法来执行此操作?

P.S. 在任何人开始告诉我为什么不应使用二进制序列化器或为什么应该使用X,Y等等以实现向后兼容性之前,请节省这些建议。 我已经了解了所有这些内容,但这不是问题所在。


4
你看到了InnerException吗?如果没有更多信息,那么可以吗? - DesignFirst
1
@casperOne 是的,我深刻地意识到了寻找序列化错误的乐趣。;p - Marc Gravell
@DesignFirst InnerException 是 Nothing - dr. evil
马克,说实话我甚至不知道有多少。你知道序列化会非常快地失控 :) - dr. evil
@Kernow,我无法反序列化数据,因为它是使用旧版本存储的,所以我一直在收到错误。理论上,我可以使用旧版本并重新编译等等来解决问题,但这需要很长时间,因此违背了提问的目的 :) - dr. evil
显示剩余5条评论
3个回答

10
如果您启用了框架代码的调试(请参见此链接),然后按下ctrl + shift + e并选择所有托管代码异常,错误将出现在实际失败的源行中。然后,您应该能够使用堆栈跟踪找出它在那一点尝试反序列化对象的哪个部分。
虽然不容易,但这就是我们最终采取的方法。

在上述情况下添加第一次机会异常并使用符号是一个很好的方法。 - Greg Levenhagen
好的,这听起来是个不错的主意,我会去看看。 - dr. evil
默认情况下,VS 2015和17中的快捷键是CTRL + ALT + E。 - Piotr Falkowski
链接是403,但这里有一个类似的问答:https://dev59.com/3VQJ5IYBdhLWcg3wBRA4 - derekbaker783

1

有几件不同的事情可以做,但都不是很好。特别是在二进制序列化方面。您可以使用ISerializable接口添加自定义序列化处理,这将允许您在调试器中逐步执行反序列化过程。

您是否考虑过切换到Xml序列化以进行开发/调试?使用Xml序列化可以使用更多的钩子。但是,看起来这对您没有用,因为您可能正在处理远程接口或存储在磁盘上的旧二进制数据需要读取。

但更简单的方法是查看源代码控制系统的日志,找到更改类型的方法。


我们目前正在检查以前的版本以解决问题,但我希望能找到一个聪明的工具来帮助我。也许当我把我的DLLs交给它时,它可以反序列化并可视化对象。太乐观了,是吧? :) - dr. evil
是的,有许多情况下,.Net异常信息中包含非常少或几乎没有信息。真是太遗憾了。当您拥有自定义类时,配置类也会抛出一些非常神秘的异常信息。至少您知道它是类型更改,这会给您一个良好的起点。 - MonkeyWrench

1

查看内部堆栈跟踪可能是有用的。 序列化程序会生成一个专门处理你想要序列化/反序列化的类型的类。

仅通过查看堆栈跟踪中涉及的函数名称,您就可以追踪到哪个节点正在出问题。

这有助于缩小问题可能存在的范围,特别是对于大型复杂的XML文件。

示例:

  at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Xml.XmlConvert.ToInt32(String s)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderXML.Read13_Item(Boolean isNullable, Boolean checkType) //Tells you the issue is on the RootNodeSubNodeSubSubNode on an item withing it.
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderXML.Read17_RootNodeSubNodeSubSubNode(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderXML.Read26_RootNodeSubNode(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderXML.Read50_RootNode(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderXML.Read51_RootNode()

2
如何知道它正在访问哪个属性。我得到了“输入字符串的格式不正确”的错误。我有一个很大的XML文件,其中包含许多属性。我想知道是哪个属性导致了问题。 - Ziggler

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