|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
Здравствуйте! Пытаюсь сериализовать объект исключения с помощью BinaryFormatter. В файл данные какие-то записываются, но на 100% не уверен, что корректно. Файл, в который пишется объект, не пуст. Код класса моего исключения: [Serializable] class R_aOutOfRangeException : ApplicationException,ISerializable { private Type my_TargetSite_DeclaringType; private string my_StackTrace; public Type my_TargSite_DecType { get { return (my_TargetSite_DeclaringType); } set { my_TargetSite_DeclaringType = value; } } public string my_StTr { get { return (my_StackTrace); } set { my_StackTrace = value; } } public R_aOutOfRangeException() { MessageBox.Show("Application Layer Error: The value entered is out of range (you must enter a positive number)."); } public new void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("pr1", my_TargetSite_DeclaringType/*TargetSite.DeclaringType*/, typeof(Type)); info.AddValue("pr2", my_StackTrace/*StackTrace*/, typeof(string)); } public R_aOutOfRangeException(SerializationInfo info, StreamingContext context) : base(info, context) { my_TargetSite_DeclaringType=(Type) info.GetValue("pr1", typeof(Type)); my_StackTrace= (string) info.GetValue("pr2",typeof(string)); } } Вызывающий код (блок catch для моего исключения): catch (R_aOutOfRangeException e) { Console.WriteLine("Exception in {0}", e.TargetSite.DeclaringType); Console.WriteLine("Stack: {0}", e.StackTrace); BinaryFormatter bf = new BinaryFormatter(); using (Stream stream = new FileStream("range_exception_error.dat", FileMode.Create, FileAccess.Write, FileShare.None)) { bf.Serialize(stream, e); } using (Stream stream = File.OpenRead("range_exception_error.dat")) { try { R_aOutOfRangeException ex = (R_aOutOfRangeException)bf.Deserialize(stream); } catch (System.Reflection.TargetInvocationException se) { Console.WriteLine("MESSAGE: {0}",se.Message); }; } } В строке, где непосредственно производится десериализация (R_aOutOfRangeException ex = (R_aOutOfRangeException)bf.Deserialize(stream);) происходит исключение System.Reflection.TargetInvocationException. В исключении выдаётся сообщение: "Адресат вызова создал исключение". Прошу помочь с решением данной проблемы. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2014, 21:38 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
AN90, 1 под отладчиком можно посмотреть детали исключения ( что там у вас не десериализовалось в каком месте) 2 зачем наследоваться от ApplicationException вполне разумно от Exception 3 конкретно по ошибке http://social.msdn.microsoft.com/Forums/en-US/a7c5436e-7788-4aa9-a825-01eaadebd0f1/problem-creating-correct-unit-tests-for-exceptions?forum=vststest ps Вас не убивает нотация или это корпоративный дресс-код ? ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2014, 23:06 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
AN90, тип R_aOutOfRangeException реализован с ошибками: - Метод GetObjectData должен быть override вместо new - Внутри GetObjectData нужно вызвать base.GetObjectData(info, context); Кроме этого: - Конструктор сериализации должен быть protected т.к. он не предназначен для пользователя - Вызывать MessageBox в конструкторе исключения очень плохая идея. В коде исключения вообще не должно быть взаимодействия с UI. Это забота кода обработки - Исключение это контейнер для информации в режиме только-чтение. Поэтому в свойствах нужно оставить только get. Инициализацию сделать через конструктор - В классе нет конструктора позволяющего передать innerException - Объявление что R_aOutOfRangeException реализует ISerializable избыточно т.к. System.Exception уже реализует его. - Ключам сериализации нужно давать нормальные имена, а не pr1 и pr2 - Возможно тебе не нужно поле StackTrace т.к. искючение уже содержит эту информацию - Ну и схема именования у тебя ужасная. Ненужный префикс my. Непоянтный префикс R_a. В обшем класс лучше переписать так: Код: c# 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36.
Зачем нужно сериализовывать исключение? Зачем тебе поля с типом и трассировкой? Если тебе нужно спец исключение для только-положительных чисел, то может лучше унаследоваться от OutOfRangeException, переопределить сообщение и не добавлять никаких полей. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2014, 23:36 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
Где-то в степи, наследовать ApplicationException есть смысл потому, что, имея объект исключения, можно определить его тип и, соответственно, сделать вывод о его происхождении: исключение приложения или системное. Спасибо за ссылку, основную мысль понял, но не всё ясно. Надо создать и инициализировать переменную с типом SerializationInfo, но неужели нужно добавление всех значений прописывать? И я не могу понять, где вышеуказанный код должен располагаться. По поводу дресс-кода вообще не понял. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2014, 13:10 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
bazile, спасибо за замечания, но думаю моя проблема не из-за этого, а из-за переменной SerializationInfo. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2014, 13:11 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
Сделал следующее: добавил в GetObjectData строку base.GetObjectData(info, context);. Инициализировал свои поля в исключении в вызывающем коде. Проблема после этого не была замечена, но не очень понял как так получилось. Почему надо вызывать base.GetObjectData? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2014, 13:36 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
Сделал следующее: добавил в GetObjectData строку base.GetObjectData(info, context);. Инициализировал свои поля в исключении в вызывающем коде. Проблема после этого не была замечена, но не очень понял как так получилось. Почему надо вызывать base.GetObjectData? ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2014, 13:40 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
AN90, ApplicationException наследует Exception который в свою очередь наследует ISerializable, и реализовывает вы же создались целью написать свою реализацию ISerializable, перекрыв базовую через new. ну если вы так сделали будь те любезны реализовать полностью десериализацию базовых типов (не только ваших) дал ссылку нотация( в данном контексте) - стандарт оформления кода ( верблюжья нотация, венгерская нотация) ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2014, 14:07 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
AN90думаю моя проблема не из-за этого, а из-за переменной SerializationInfo. Прооблема в отсутствии вызова base.GetObjectData(info, context) и в new вместо правильного override. Остальтные 8 пунктов это пожелания, но я не советую тебе их игнорировать. Вызов GetObjectData необходим чтобы базовый класс добавил в контекст серилизации свои данные. Каждый класс отвечает только за свои поля. При сериализации вызывается GetObjectData и всё классы в иерархии нследования должны добавить данные - поэтому нужно вызвать реализацию GetObjectData своего базоового класса. При десериализации нужно прочитать данные обратно. Этим занимается конструктор приниммающий SerializationInfo и StreamingContext. Там тоже необходим вызов базового конструктора. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.09.2014, 16:22 |
|
Проблема с десериализацией
|
|||
---|---|---|---|
#18+
Большое спасибо за ответы! ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2014, 21:44 |
|
|
start [/forum/topic.php?fid=20&tid=1402472]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
38ms |
get topic data: |
15ms |
get forum data: |
3ms |
get page messages: |
48ms |
get tp. blocked users: |
2ms |
others: | 335ms |
total: | 473ms |
0 / 0 |