整体代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace ConsoleLearn
{
//继承json用转换器
public class InheritanceConverter<T> : JsonConverter<T> where T : class
{
//子类字典 key:为子类属性名 value为子类类型
private Dictionary<string, Type> _dictionay = new Dictionary<string, Type>();
public InheritanceConverter(Dictionary<string, Type> dictionary)
{
_dictionay = dictionary;
}
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsAssignableFrom(typeof(T));
}
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null)
return null;
if (JsonDocument.TryParseValue(ref reader, out var doc))
{
var jsonObject = doc.RootElement;
foreach (var key in _dictionay.Keys)
{
if (doc.RootElement.TryGetProperty(key, out var propertyValue))
{
var type = _dictionay[key];
var rootText = jsonObject.GetRawText();
return (T)JsonSerializer.Deserialize(rootText, type);
}
}
return null;
}
return null;
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
if(value is T t && value.GetType()==typeof(T))
{
JsonSerializer.Serialize(writer, t);
}
else
JsonSerializer.Serialize(writer, (object)value);
}
}
//父
public class Parent
{
public string Name { get; set; }
}
//孩子1
public class Child1 : Parent
{
public int Age { get; set; }
public List<GrandSon> GrandSons { get; set; }
}
//孩子2
public class Child2: Parent
{
public string Birthday { get; set; }
}
//孙子
public class GrandSon :Child1
{
public string Hobby { get; set; }
}
public class TestJson2
{
public static void Test()
{
List<Parent> list = new List<Parent>
{
new Parent { Name = "父亲"},
new Child1 { Name="孩子1", Age = 18, GrandSons = new List<GrandSon>{ new GrandSon { Age =1 , Name = "孩子1的孙子", Hobby="美女"} } },
new Child2 {Name="孩子2",Birthday = "2004-02-02"},
new GrandSon {Name="孙子1",Hobby ="篮球"}
};
// 字典的key指的是子类或基类独有的属性, value指对应的类的Type。这里有顺序 要求 如果子类 层级越深 key顺序越靠前, 层级越浅 顺序越靠后 同级子类顺序无所谓
Dictionary<string, Type> dic = new Dictionary<string, Type>
{
["Hobby"] = typeof(GrandSon),
["Birthday"] = typeof(Child2),
["Age"] = typeof(Child1),
["Name"] = typeof(Parent)
};
//序列化测试
string json = JsonSerializer.Serialize(list,
new JsonSerializerOptions {
Converters = { new InheritanceConverter<Parent>(dic) },
WriteIndented=true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
Console.WriteLine(json);
//反序列化测试
List<Parent> ret = JsonSerializer.Deserialize<List<Parent>>(json,
new JsonSerializerOptions {
Converters = { new InheritanceConverter<Parent>(dic) },
WriteIndented = true,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping });
Console.ReadLine();
}
}
}
输出结果: