Как отлаживать ошибки десериализации в .NET? - PullRequest
21 голосов
/ 03 февраля 2011

. Ошибки десерилизации .NET являются довольно общими, например, что-то вроде этого:

System.ArgumentException: объект тип 'System.Uri' не может быть преобразован набрать 'System.String'.

Понятно, что мы изменили тип свойства в объекте, но в этом сериализованном объекте есть примерно 10-15 различных классов, так что очень трудно понять, какой из них мы изменили или какой коммит испортил это. *

Есть ли способ получить информацию о том, какое свойство в каком классе ( или, по крайней мере, в каком классе ) действительно вызывает эту ошибку? Есть ли какой-нибудь внешний инструмент или известные способы сделать это?

P.S. Прежде чем кто-нибудь скажет мне, почему я не должен использовать двоичный сериализатор или почему вместо него следует использовать X, Y и т. Д., Пожалуйста, сохраните рекомендации по ним. Я знаю обо всем этом, но это не вопрос.

Ответы [ 3 ]

8 голосов
/ 04 февраля 2011

Если вы включите отладку в код фреймворка (см. эту ссылку), а затем нажмите Ctrl + Shift + E и выберите все исключения управляемого кода, ошибка будет отображаться в фактической исходной строке, которая не работает.Затем вы сможете использовать трассировку стека, чтобы выяснить, какую часть объекта он пытается десериализовать в этой точке.

Это не легко, но именно так мы и сделали.

1 голос
/ 15 ноября 2013

Просмотр трассировки внутреннего стека может быть полезен.Сериализатор генерирует класс специально для обработки типа, который вы хотите сериализовать / десериализовать.

Просто взглянув на имена функций функций, участвующих в трассировке стека, вы можете отследить, какой узел узла ломается.

Это помогает сузить суть проблемы, особенно с большими сложными файлами 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()
1 голос
/ 04 февраля 2011

Есть пара разных вещей, которые вы можете сделать, но ни одна из них не хороша.Особенно с двоичной сериализацией.Вы можете добавить настраиваемую обработку сериализации с помощью интерфейса ISerializable , который позволит вам выполнить процесс десериализации в отладчике.

Рассматривали ли вы переход к сериализации Xml для целей разработки / отладки?Есть еще несколько хуков, которые вы можете использовать с сериализацией Xml.Но, похоже, это не сработает, потому что вы, вероятно, имеете дело с удаленным интерфейсом или более старыми двоичными данными, хранящимися на диске, которые вам нужно прочитать.

Но еще проще было бы просмотретьжурналы вашей системы контроля версий для метода с измененным типом.

...