Подтвердить что ты не робот

Как отлаживать ошибки десериализации в .NET?

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

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

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

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

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

4b9b3361

Ответ 1

Если вы включите отладку в код фрейма (см. эту ссылку), а затем нажмите ctrl + shift + e и выберите все исключения управляемых кодов, ошибка появится в фактическом исходная строка не работает. Вы должны иметь возможность использовать трассировку стека, чтобы выяснить, какая часть объекта, который он пытался десериализовать в этой точке.

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

Ответ 2

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

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

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

Ответ 3

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

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

Это помогает сузить место, где может быть проблема, особенно с большими сложными 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()