Сериализация исключений .NET больше не работает без устаревшего шаблона – намеренно?C#

Место общения программистов C#
Ответить
Anonymous
 Сериализация исключений .NET больше не работает без устаревшего шаблона – намеренно?

Сообщение Anonymous »

Наконец-то мне захотелось удалить устаревший шаблон с [SerializableAttribute], protected ctor и GetObjectData(SerializationInfo, StreamingContext) из моих исключений.
Сейчас сериализаторы, как System.Text.Json.JsonSerializer, так и Newtonsoft.Json.JsonConvert, не десериализуют исключение правильно:
хотя и не полагаясь на старый IFormatter (действительно нет?), [edit] Newtonsoft.Json сериализовал и десериализовал исключения, реализующие старый шаблон. Теперь при десериализации даже не воспроизводится исходное сообщение об исключении, а при десериализации SomeIdNotFoundException создается новое сообщение:

Исключение типа '... .SomeIdNotFoundException'.

Я вижу, что классы исключений, как пользовательские, так и распространенные типы .NET, включая базовый System.Exception, не подходит обычные требования к (де)сериализации, заключающиеся в наличии частных/защищенных и доступных только для чтения членов, но намеренно ли потерять весь контент исключений, если не использовать специальные конфигурации?
Изменить: Пример< /h2>
С устаревшей сериализацией

Код: Выделить всё

[Serializable]
public class SomeIdNotFoundException : Exception
{
public SomeIdNotFoundException()
{ }

public SomeIdNotFoundException(string message)
: base(message)
{ }

public SomeIdNotFoundException(string message, Exception innerException)
: base(message, innerException)
{ }

protected SomeIdNotFoundException(SerializationInfo info, StreamingContext context)
: base(info, context)
{ }

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
Без устаревшей сериализации

Код: Выделить всё

public class SomeIdNotFoundException : Exception
{
public SomeIdNotFoundException()
{ }

public SomeIdNotFoundException(string message)
: base(message)
{ }

public SomeIdNotFoundException(string message, Exception innerException)
: base(message, innerException)
{ }
}

Код: Выделить всё

[TestMethod]
public void SomeIdNotFoundException_Serialization_RoundTrip()
{
var expectedMessage = "Some ID not found.";
var originalException = new SomeIdNotFoundException(expectedMessage);
//var originalException = Assert.ThrowsException(
//    () => throw new SomeIdNotFoundException(expectedMessage));

var deserializedException = SerializeAndDeserialize(originalException);

Assert.AreEqual(expectedMessage, deserializedException.Message);
}

private static SomeIdNotFoundException SerializeAndDeserialize(SomeIdNotFoundException exceptionToSerialize)
{
//var serializedException = System.Text.Json.JsonSerializer.Serialize(exceptionToSerialize);
//return System.Text.Json.JsonSerializer.Deserialize(serializedException)!;
var serializedException = Newtonsoft.Json.JsonConvert.SerializeObject(exceptionToSerialize);
return Newtonsoft.Json.JsonConvert.DeserializeObject(serializedException)!;
Прямое создание экземпляра исключения (без выдачи)

С отключенным устаревшим шаблоном

Десериализация с обоими, System и Newtonsoft, сериализаторы генерируют новое сообщение об исключении такого типа:

Исключение типа '[namespace ].SomeIdNotFoundException' было выброшено.

С устаревшим шаблоном все еще доступен

  • System.Text .Json ведет себя так же, как и устаревший шаблон, создавая десериализованное исключение с новым сообщением об исключении.
  • Newtonsoft.Json выполняет полную десериализацию метода. , сохраняя исходное сообщение.
Создание исключения
Создание исключения, как в закомментированной части с Assert.ThrowsException(...). Тогда десериализация никогда не будет работать с System.Text.Json, независимо от того, реализован ли устаревший шаблон.
Сообщения об ошибках для выброшенных исключение с System.Text.Json:

System.NotSupportedException: Сериализация и десериализация экземпляров System.Reflection.MethodBase не поддерживается. Путь: $.TargetSite. --->
System.NotSupportedException: сериализация и десериализация экземпляров System.Reflection.MethodBase не поддерживаются.

Newtonsoft.Json не имеет проблем с выдаваемыми исключениями, если доступен устаревший шаблон.

Подробнее здесь: https://stackoverflow.com/questions/792 ... n-intentio
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»