powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Проблема с десериализацией
11 сообщений из 11, страница 1 из 1
Проблема с десериализацией
    #38746106
AN90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте! Пытаюсь сериализовать объект исключения с помощью 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. В исключении выдаётся сообщение: "Адресат вызова создал исключение". Прошу помочь с решением данной проблемы.
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746131
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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 Вас не убивает нотация или это корпоративный дресс-код ?
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746145
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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.
[Serializable]
class TypedOutOfRangeException : ApplicationException
{
	private Type declaringType;
	private string errorStackTrace;

	public Type DeclaringType { get { return declaringType; } }
	public string ErrorStackTrace { get { return errorStackTrace; } }

	public TypedOutOfRangeException(Type declaringType, string errorStackTrace)
		: this(declaringType, errorStackTrace, null)
	{
	}

	public TypedOutOfRangeException(Type declaringType, string errorStackTrace, Exception innerException)
		: base("Application Layer Error: The value entered is out of range (you must enter a positive number).", innerException)
	{

		this.declaringType = declaringType;
		this.errorStackTrace = errorStackTrace;
	}

	public override void GetObjectData(SerializationInfo info, StreamingContext context)
	{
		info.AddValue("DeclaringType"  , declaringType);
		info.AddValue("ErrorStackTrace", errorStackTrace);
		base.GetObjectData(info, context);
	}

	protected TypedOutOfRangeException(SerializationInfo info, StreamingContext context)
		: base(info, context)
	{
		declaringType = (Type)info.GetValue("DeclaringType", typeof(Type));
		errorStackTrace = (string)info.GetValue("ErrorStackTrace", typeof(string));
	}
}


Зачем нужно сериализовывать исключение? Зачем тебе поля с типом и трассировкой? Если тебе нужно спец исключение для только-положительных чисел, то может лучше унаследоваться от OutOfRangeException, переопределить сообщение и не добавлять никаких полей.
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746236
AN90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степи,

наследовать ApplicationException есть смысл потому, что, имея объект исключения, можно определить его тип и, соответственно, сделать вывод о его происхождении: исключение приложения или системное. Спасибо за ссылку, основную мысль понял, но не всё ясно. Надо создать и инициализировать переменную с типом SerializationInfo, но неужели нужно добавление всех значений прописывать? И я не могу понять, где вышеуказанный код должен располагаться. По поводу дресс-кода вообще не понял.
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746237
AN90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bazile,

спасибо за замечания, но думаю моя проблема не из-за этого, а из-за переменной SerializationInfo.
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746247
AN90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал следующее: добавил в GetObjectData строку base.GetObjectData(info, context);. Инициализировал свои поля в исключении в вызывающем коде. Проблема после этого не была замечена, но не очень понял как так получилось. Почему надо вызывать base.GetObjectData?
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746249
AN90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделал следующее: добавил в GetObjectData строку base.GetObjectData(info, context);. Инициализировал свои поля в исключении в вызывающем коде. Проблема после этого не была замечена, но не очень понял как так получилось. Почему надо вызывать base.GetObjectData?
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746258
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AN90,
ApplicationException наследует Exception который в свою очередь наследует ISerializable, и реализовывает
вы же создались целью написать свою реализацию ISerializable, перекрыв базовую через new.
ну если вы так сделали будь те любезны реализовать полностью десериализацию базовых типов (не только ваших)
дал ссылку
нотация( в данном контексте) - стандарт оформления кода ( верблюжья нотация, венгерская нотация)
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38746285
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AN90думаю моя проблема не из-за этого, а из-за переменной SerializationInfo.
Прооблема в отсутствии вызова base.GetObjectData(info, context) и в new вместо правильного override. Остальтные 8 пунктов это пожелания, но я не советую тебе их игнорировать.

Вызов GetObjectData необходим чтобы базовый класс добавил в контекст серилизации свои данные. Каждый класс отвечает только за свои поля. При сериализации вызывается GetObjectData и всё классы в иерархии нследования должны добавить данные - поэтому нужно вызвать реализацию GetObjectData своего базоового класса. При десериализации нужно прочитать данные обратно. Этим занимается конструктор приниммающий SerializationInfo и StreamingContext. Там тоже необходим вызов базового конструктора.
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38747268
AN90
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Большое спасибо за ответы!
...
Рейтинг: 0 / 0
Проблема с десериализацией
    #38747275
bazile
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AN90, поясни все-таки зачем тебе понадобилось сериализовать исключение и зачем тебе поле с трассировкой стека когда оно уже есть в классе Exception?
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Проблема с десериализацией
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]