Сейчас сериализаторы, как System.Text.Json.JsonSerializer, так и Newtonsoft.Json.JsonConvert, не десериализуют исключение правильно:
хотя и не полагаясь на старый IFormatter (действительно нет?), [edit] Newtonsoft.Json сериализовал и десериализовал исключения, реализующие старый шаблон. Теперь при десериализации даже не воспроизводится исходное сообщение об исключении, а при десериализации SomeIdNotFoundException создается новое сообщение:
Исключение типа '... .SomeIdNotFoundException'.
Я вижу, что классы исключений, как пользовательские, так и распространенные типы .NET, включая базовый System.Exception, не подходит обычные требования к (де)сериализации, заключающиеся в наличии частных/защищенных и доступных только для чтения членов, но намеренно ли потерять весь контент исключений, если не использовать специальные конфигурации?
Изменить: Пример< /h2>
С устаревшей сериализацией
Код: Выделить всё
using System;
using System.Runtime.Serialization;
[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);
}
}
Код: Выделить всё
using System;
public class SomeIdNotFoundException : Exception
{
public SomeIdNotFoundException()
{ }
public SomeIdNotFoundException(string message)
: base(message)
{ }
public SomeIdNotFoundException(string message, Exception innerException)
: base(message, innerException)
{ }
}
Код: Выделить всё
using System;
using System.Runtime.Serialization;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[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();
}
}
С отключенным устаревшим шаблоном
Десериализация с обоими, 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
Мобильная версия