C# 为什么System.Text Json Serialiser不序列化此泛型属性,而Json.NET序列化此泛型属性?
我有以下情况。我已将问题简化为以下示例,尽管我的实际情况更为复杂 System.Text.Json不会完全序列化对象,但Newtonsoft Json.NET会 假设我有下面的类结构C# 为什么System.Text Json Serialiser不序列化此泛型属性,而Json.NET序列化此泛型属性?,c#,.net-core,json.net,system.text.json,C#,.net Core,Json.net,System.text.json,我有以下情况。我已将问题简化为以下示例,尽管我的实际情况更为复杂 System.Text.Json不会完全序列化对象,但Newtonsoft Json.NET会 假设我有下面的类结构 public class A { public string AProperty { get; set; } = "A"; } public class A<T> : A where T : class, new() { public T TObject { get; set; } =
public class A
{
public string AProperty { get; set; } = "A";
}
public class A<T> : A where T : class, new()
{
public T TObject { get; set; } = new T();
}
public class B
{
public string BProperty { get; set; } = "B";
}
public class B<T> : B where T : class, new()
{
public T TObject { get; set; } = new T();
}
public class C
{
public string CProperty { get; set; } = "C";
}
纽顿软件
由于我的应用程序的结构,我不知道B
的泛型参数。我只知道它是一个A
。B
的实际TObject
直到运行时才知道
为什么这两种序列化方法不同?有没有办法让System.Text.Json完全序列化对象,或者我需要编写一个自定义转换器?这是
System.Text.Json
的一个文档限制。从:
序列化派生类的属性
不支持多态类型层次结构的序列化。例如,如果将属性定义为接口或抽象类,则即使运行时类型具有其他属性,也仅序列化在接口或抽象类上定义的属性。此行为的例外情况将在本节中进行解释。。。。
要序列化[a]派生类型的属性,请使用以下方法之一:
对象
A.TObject
被声明为类型B
,但在您构造的实例中实际上是类型B
,因此只有基类B
的属性按照文档进行序列化。就这样。有关进一步讨论,请参阅已结束的问题
然而,有几种变通方法可用。首先,您可以将obj
构造为其最可能的派生类型A
:
var obj=newa{TObject=newb()};
现在,TObject
的所有属性都被序列化。演示小提琴#1。但不幸的是,您无法使用此解决方法,因为B
的实际TObject
直到运行时才知道
或者,如果您只需要序列化您的obj
,您可以按照文档中的建议2,声明一个对象类型的代理属性,并序列化:
public class A:A其中T:class,new()
{
[System.Text.Json.Serialization.JsonPropertyName(“TObject”)]
[Newtonsoft.Json.JsonIgnore]
公共对象SerializedObject=>ToObject;
[System.Text.Json.Serialization.JsonIgnore]
公共T TObject{get;set;}=new T();
}
请注意,不能为要序列化的只读属性设置
演示小提琴2
最后,如果需要多态序列化和反序列化,则需要编写一个自定义的。开始看
您可以编写自定义转换器或等待.NET 5发布,因为JSON.NET要好得多
public class Program
{
private static void Main(string[] args)
{
var obj = new A<B> { TObject = new B<C>() };
var systemTextSerialized = JsonSerializer.Serialize(obj);
var newtonsoftSerialized = JsonConvert.SerializeObject(obj);
}
}
{
"TObject": {
"BProperty": "B"
},
"AProperty": "A"
}
{
"TObject": {
"TObject": {
"CProperty": "C"
},
"BProperty": "B"
},
"AProperty": "A"
}