Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Проблема с десериализацией / 11 сообщений из 11, страница 1 из 1
13.09.2014, 21:38
    #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
13.09.2014, 23:06
    #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
13.09.2014, 23:36
    #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
14.09.2014, 13:10
    #38746236
AN90
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с десериализацией
Где-то в степи,

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

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

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


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