『 再看.NET7』让json序列化体现多态
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了『 再看.NET7』让json序列化体现多态相关的知识,希望对你有一定的参考价值。
从System.Text.Json诞生,就在努力增加功能和提升性能,在.NET7中,又带来了多态的适配。
下面是一个父类Customer,两个子类,WechatCustomer和LineCustomer。
public class Customer
public string Name get; set;
public string Address get; set;
public string City get; set;
public string Region get; set;
public string PostalCode get; set;
public string EMail get; set;
public string Tel get; set;
public class WechatCustomer : Customer
public string? WechatNo get; set;
public class LineCustomer : Customer
public string? LineNo get; set;
分别用一个打印方法PrintCustomer输出两个子类对象。
var wechatCustomer = new WechatCustomer
Name = "张三",
City = "东京",
Region = "中央区",
Address = "1-56-326",
PostalCode = "3000235",
EMail = "abcde@gmail.com",
Tel = "08-9563-2356",
WechatNo = "wechat_gsw"
;
var lineCustomer = new LineCustomer
Name = "张三",
City = "东京",
Region = "中央区",
Address = "1-56-326",
PostalCode = "3000235",
EMail = "abcde@gmail.com",
Tel = "08-9563-2356",
LineNo = "line_gsw"
;
//共用打印方法
void PrintCustomer(Customer customer)
var options = new JsonSerializerOptions
Encoder = javascriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = true
;
var json = JsonSerializer.Serialize<Customer>(customer, options);
Console.WriteLine(json);
PrintCustomer(wechatCustomer);
PrintCustomer(lineCustomer);
输出结果是:
"Name": "张三",
"Address": "1-56-326",
"City": "东京",
"Region": "中央区",
"PostalCode": "3000235",
"EMail": "abcde@gmail.com",
"Tel": "08-9563-2356"
"Name": "张三",
"Address": "1-56-326",
"City": "东京",
"Region": "中央区",
"PostalCode": "3000235",
"EMail": "abcde@gmail.com",
"Tel": "08-9563-2356"
现在丢失了子类的属性WechatNo和LineNo,在.NET7中,可以通过两种方式来保证不丢失这种多态产生的新的属性:特性和自定义类型信息解析器。
特性:
[JsonPolymorphic(TypeDiscriminatorPropertyName = "CustomerType")]
[JsonDerivedType(typeof(WechatCustomer), typeDiscriminator: "wechatCustomer")]
[JsonDerivedType(typeof(LineCustomer), typeDiscriminator: "lineCustomer")]
public class Customer
……
通过给父类Customer添加特性,来达到json化的效果。再次输出如下:
"CustomerType": "wechatCustomer",
"WechatNo": "wechat_gsw",
"Name": "张三",
"Address": "1-56-326",
"City": "东京",
"Region": "中央区",
"PostalCode": "3000235",
"EMail": "abcde@gmail.com",
"Tel": "08-9563-2356"
"CustomerType": "lineCustomer",
"LineNo": "line_gsw",
"Name": "张三",
"Address": "1-56-326",
"City": "东京",
"Region": "中央区",
"PostalCode": "3000235",
"EMail": "abcde@gmail.com",
"Tel": "08-9563-2356"
可以看到,JsonPolymorphic特性是定义一个标注子类名称的属性customerType,而JsonDerivedType是定义两个子类的特性。
自定义类型信息解析器:
首先定义自定义类型信息解析器class,可以看出,他的作用与上面的特性是一样的。
public class PolymorphicTypeResolver : DefaultJsonTypeInfoResolver
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);
Type basePointType = typeof(Customer);
if (jsonTypeInfo.Type == basePointType)
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions
TypeDiscriminatorPropertyName = "CustomerType",
DerivedTypes =
new JsonDerivedType(typeof(WechatCustomer), "wechatCustomer"),
new JsonDerivedType(typeof(LineCustomer), "lineCustomer")
;
return jsonTypeInfo;
这个时候,Customer上的特性就可以没有了,只要在PrintCustomer方法中给options加个属性即可。
void PrintCustomer(Customer customer)
var options = new JsonSerializerOptions
TypeInfoResolver = new PolymorphicTypeResolver(),
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = true
;
var json = JsonSerializer.Serialize<Customer>(customer, options);
Console.WriteLine(json);
输出结果与特性方式是一样的。这里不再赘述。
上面两种方式,也可以把对应的json字符串反序列化回来。
以上是关于『 再看.NET7』让json序列化体现多态的主要内容,如果未能解决你的问题,请参考以下文章