Бросок сериализации ArgumentException / InvalidCastException: необходим подход отладки - PullRequest
1 голос
/ 08 декабря 2011

У нас есть веб-решение со смешанными проектами C # и VB.NET (3.5) (примечание: в некоторых файлах vb.net Option Strict Off). Наш код работает как модули внутри DotNetNuke 4.8. При определенных условиях наше приложение будет аварийно завершать работу по методу:

System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteString

Сокращенное сообщение в этом исключении:

System.ArgumentException: "Error serializing value XYZ of type XYZ."
System.InvalidCastException: "Unable to cast object of type 'System.Int64' 
to 'System.String'"

Нигде в трассировке стека нет нашего кода, это просто системный код, который в итоге не может сериализовать тип XYZ из нашего кода. Это означает, что я не могу достичь точки останова и отладить, какое именно свойство XYZ является проблемой. Свойство трассировки стека пусто, но в сообщении есть трассировка стека, сокращенно обозначенная как:

DotNetNuke.Services.Exceptions.PageLoadException: "Error serializing value 'XYZ' of type 'XYZ.'" 
  System.ArgumentException: "Error serializing value 'XYZ' of type 'XYZ.'" 
  System.InvalidCastException: "Unable to cast object of type 'System.Int64' to type 'System.String'. "
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteString(NameInfo memberNameInfo, NameInfo typeNameInfo, Object stringObject)
// ...... etc.........
at System.Web.UI.Page.SaveAllState() 
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 
// --- End of inner exception stack trace

Все соответствующие строки в этой трассировке начинаются с System.. Верхние строчки - это DotNetNuke. Однако, следуя предложению первого ответа, я сам скомпилировал код DotNetNuke (4.8) и выяснил, что код просто выполняет Server.GetLastError, показывая InvalidCastException в качестве InnerException без какой-либо дополнительной информации о фактическом значении или имени свойства, которые сериализуются.

Тогда возникает вопрос : как мне узнать, с каким полем и значением у сериализатора возникли проблемы?

Несколько связанных вопросов / проблем, которые пришли в голову при исследовании этой проблемы:

  • Если я посмотрю на Formatters.Binary часть MSDN, я бы предположил, что ObjectWriter является внутренним для Binary (как это предлагается в комментариях, красный)?
  • Как .NET может вообще прервать приведение Int64 к String? Перефразировано: какое значение для Int64 потенциально не может быть преобразовано в строку? Однако, как отмечено в комментариях: Int64 можно легко преобразовать в строки, но приведение к ним - другая проблема.
  • Метод Serialize не сообщает об этом ArgumentException, иначе может возникнуть InvalidCastException (в разделе «Исключения»).

Я пытался исследовать XYZ и типы для свойств в этом классе в ildasm, чтобы увидеть любые нарушения, но не смог их найти.

Ответы [ 2 ]

2 голосов
/ 08 декабря 2011

Вы не упомянули, что такое трассировка стека - хотя это может быть неактуально.

Если это в коде DotNetNuke, я бы загрузил исходный код DotNetNuke в ваш отладчик и заново создал исключение. Вы также можете скомпилировать исходный код DotNetNuke (соответствующая версия) и просто сбросить вновь скомпилированные файлы dll и .pdb в каталог \ bin.

Как только вы это настроите, перейдите в Visual Studio -> Отладка, Исключения и поставьте флажок рядом с «Общими исключениями времени исполнения языка» в столбце «Брошенный». Вы также можете поэкспериментировать с «нативными проверками времени выполнения».

Затем воссоздайте свой тест. Код должен сломаться в момент, когда выдается исключение. Когда это произойдет, вы сможете не только отслеживать трассировку стека, но и определять значение, вызывающее проблему.

Обратите внимание, что при использовании этого подхода вы столкнетесь с множеством других исключений - есть места, где try / catch используется как способ обработки кода, и все они появятся. Вам нужно будет просто пройтись по этим примерам, пока не найдете тот, который вам нужен.

Если все остальное терпит неудачу, я перекомпилирую с «try / catch» в нем и записываю / прерываю ошибочные значения, но вам не нужно заходить так далеко. Достаточно просто отключить Visual Studio при появлении ошибки, чтобы изолировать проблему.

0 голосов
/ 09 декабря 2011

Отвечая на мой собственный вопрос, надеюсь, это поможет любому, кто окажется здесь после поискового запроса.

Окончательный ответ был найден в этом ТАК вопросе .В итоге я использовал пробную версию .NET Reflector (и включенный плагин Visual Studio 2010), чтобы войти в код mscorlib.Это позволило мне проверить NameInfo для свойства, которое вызывало InvalidCastException.

Короче говоря, ответ был: используйте .NET Reflector (или аналогичный инструмент), чтобы войти в mscorlib.


PS.Хотя вступление в mscorlib было ответом на мою проблему, поставленную в этом вопросе, все еще есть основная проблема, которая, вероятно, требует совершенно нового SO вопроса, как только я соберу достаточно информации о нем.

...