(原创)System.Text.Json继承处理

整体代码

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();
        }
    }
}

输出结果:

  • 1
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

Eclipse小乖

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值