这个问题指的是仍然使用Newtonsoft.Json的代码。以下测试也使用了 System.Text.Json。
我最终想从我的例外中删除过时的模式,包括
[SerializableAttribute]
、受保护的 ctor 和 GetObjectData(SerializationInfo, StreamingContext)
。
现在序列化器,
System.Text.Json.JsonSerializer
和Newtonsoft.Json.JsonConvert
都不能正确反序列化异常:
虽然不依赖于旧的
IFormatter
(真的不是吗?),[编辑] Newtonsoft.Json 序列化和反序列化异常实现了旧模式。现在,反序列化甚至不会重现原始异常消息,而是在反序列化时创建一条新消息 SomeIdNotFoundException
:
抛出了“...SomeIdNotFoundException”类型的异常。
我发现异常类,包括自定义和常见的 .NET 类型,包括基本的
System.Exception
,通过拥有私有/受保护和只读成员,不符合(反)序列化的通常要求,但这是故意的吗丢失所有异常内容,除非使用特殊配置?
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<SomeIdNotFoundException>(
// () => 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<SomeIdNotFoundException>(serializedException)!;
var serializedException = Newtonsoft.Json.JsonConvert.SerializeObject(exceptionToSerialize);
return Newtonsoft.Json.JsonConvert.DeserializeObject<SomeIdNotFoundException>(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”类型的异常。
抛出异常,就像用
Assert.ThrowsException<SomeIdNotFoundException>(...)
注释掉的部分一样。然后,反序列化永远不会与 System.Text.Json 一起工作,无论是否实现了遗留模式。
System.Text.Json抛出的异常的错误消息:
System.NotSupportedException:不支持“System.Reflection.MethodBase”实例的序列化和反序列化。路径:$.TargetSite。 ---> System.NotSupportedException:不支持“System.Reflection.MethodBase”实例的序列化和反序列化。Newtonsoft.Json
只要遗留模式可用,就没有抛出异常的问题。
另请参阅问题下评论中来自 @dbc 的链接!