测试类:
[JsonConverter(typeof(PersonConverter))] public class Person { public string FirstName { get; set; } public string LastName { get; set; } } [JsonConverter(typeof(PersonConverter))] public class Employee : Person { public string Department { get; set; } public string JobTitle { get; set; } } [JsonConverter(typeof(PersonConverter))] public class Artist : Person { public string Skill { get; set; } }
自定义Converter:
public class PersonConverter : JsonConverter<Person> { public override Person Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { JsonDocument.TryParseValue(ref reader, out var doc); var elm = doc.RootElement; elm.TryGetProperty("isBase", out var jEl); elm.TryGetProperty("typeName", out var typeEl); elm.TryGetProperty("obj", out var objEl); var typeStr = typeEl.GetString(); var type = Type.GetType(typeStr); var objStr = objEl.GetRawText(); var dic = JsonSerializer.Deserialize<Dictionary<string, string>>(objStr); var obj = ToObject(dic, type); return obj as Person; } public override bool CanConvert(Type typeToConvert) { if (typeToConvert == typeof(Person)) return true; if (typeToConvert.BaseType == typeof(Person)) return true; return false; } public override void Write(Utf8JsonWriter writer, Person value, JsonSerializerOptions options) { var type = value.GetType(); var dic = new { typeName = type.FullName, obj = ToDictionary(value), }; JsonSerializer.Serialize(writer, dic, options); } public Dictionary<string, object> ToDictionary(object obj) { if (obj == null) throw new ArgumentNullException(nameof(obj)); var dictionary = new Dictionary<string, object>(); foreach (var property in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (property.CanRead) { dictionary[property.Name] = property.GetValue(obj, null); } } return dictionary; } public T ToObject<T>(Dictionary<string, object> source) where T : class, new() { T result = new T(); Type type = typeof(T); foreach (KeyValuePair<string, object> item in source) { PropertyInfo property = type.GetProperty(item.Key); if (property != null && property.CanWrite) { property.SetValue(result, item.Value, null); } } return result; } public object ToObject(IDictionary<string, string> source, Type type) { var result = Activator.CreateInstance(type); foreach (KeyValuePair<string, string> item in source) { PropertyInfo property = type.GetProperty(item.Key); if (property != null && property.CanWrite) { property.SetValue(result, item.Value, null); } } return result; } }
入口方法:
static void Main(string[] args) { Console.WriteLine("Hello World!"); List<Person> people = new List<Person> { new Employee(){Department="test part", FirstName="Hello", LastName="L", JobTitle="engineer"}, new Person() { FirstName="ooook", LastName="is not", }, new Artist() { FirstName="oooo", LastName="is not ooo", Skill="coding" }, }; var str = JsonSerializer.Serialize(people); Console.WriteLine(str); var pes = JsonSerializer.Deserialize<List<Person>>(str); }
思路就是:转换成特定的类,然后需要借助Dictionary转换,不然直接使用serialize会出现循环调用,或者直接再引用一个newTonsoft.json取代dictionnary与对象转换的方法,不过那样我感觉不太好。针对继承类型的集合序列化,反序列化,子类字段不缺失,值也不缺失。 标签:序列化,obj,自定义,多态,var,new,property,type,public From: https://www.cnblogs.com/HelloQLQ/p/18426418