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

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

Сообщение Anonymous »

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

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

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

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

using System;
using System.Runtime.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;

[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);
}
}

[TestClass]
public class ExceptionSerializationTests
{
[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)!;
}

public static void Main(string[] args)
{
new ExceptionSerializationTests()
.SomeIdNotFoundException_Serialization_RoundTrip();
}
}
Без устаревшей сериализации
Только класс исключений.

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

// no Serializable attribute
public class SomeIdNotFoundException : Exception
{
public SomeIdNotFoundException()
{ }

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

public SomeIdNotFoundException(string message, Exception innerException)
: base(message, innerException)
{ }
}
Прямое создание экземпляра исключения (без выдачи)

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

Десериализация с обоими, 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 ... -newtonsof
Ответить

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

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

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

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

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