开发手册 欢迎您!
软件开发者资料库

.NET(C#) Newtonsoft.JSON 自定义JsonConverter处理不同的JSON数据

本文主要介绍.NET(C#)中,使用Newtonsoft.JSON的自定义转换器JsonConverter,处理不同的JSON数据输入,能够实现对老数据的兼容。

1、JSON实体类

class Animal{    public string Name { get; set; }    public int Age { get; set; }}class BaseObj{    public Animal Animal { get; set; }}class People : BaseObj{    public DateTime StudentTime { get; set; }}class Dog : BaseObj{    public DateTime EatTime { get; set; }}

2、自定义JsonConverter(转换器)

1)自定义JsonConverter

class ObjConverter : JsonConverter{    public override bool CanConvert(Type objectType)    {        return typeof(BaseObj).IsAssignableFrom(objectType);    }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        JObject obj = JObject.Load(reader);        string type = (string)obj["$type"];        BaseObj baseObj;        if (type.Contains(nameof(People)))        {            baseObj = new People();        }        else        {            baseObj = new Dog();        }        serializer.Populate(obj.CreateReader(), baseObj);        if (baseObj.Animal == null)        {            baseObj.Animal = new Animal            {                Name = (string)obj["ObjName"],                Age = (int)obj["ObjAge"]            };        }        return baseObj;    }    public override bool CanWrite => false;    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        throw new NotImplementedException();    }}

2)反序列化

var settings = new JsonSerializerSettings{    TypeNameHandling = TypeNameHandling.Objects,    Converters = new List { new ObjConverter() }};var baseObj = JsonConvert.DeserializeObject(json, settings);

3) 完整代码

using Newtonsoft.Json;using Newtonsoft.Json.Linq;using System;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;namespace ConsoleApplication{    class Program    {        static ReaderWriterLock rwl = new ReaderWriterLock();        // 定义ReaderWriterLock对象。        static int resource = 0;        const int numThreads = 8;        static bool running = true;        static int readerTimeouts = 0;        static int writerTimeouts = 0;        static int reads = 0;        static int writes = 0;        public static void Main()        {            var settings = new JsonSerializerSettings            {                TypeNameHandling = TypeNameHandling.Objects,                Converters = new List { new ObjConverter() }            };            var setting = new Newtonsoft.Json.JsonSerializerSettings            {                TypeNameAssemblyFormatHandling = Newtonsoft.Json.TypeNameAssemblyFormatHandling.Simple,                TypeNameHandling = Newtonsoft.Json.TypeNameHandling.Objects,            };            string json = JsonConvert.SerializeObject(new Dog { Animal = new Animal { Age = 1, Name = "dog" }, EatTime = DateTime.Now }, setting);            Console.WriteLine("json = " + json);            //json = {"$type":"ConsoleApplication.Dog, ConsoleApp3","EatTime":"2022-02-25T11:0            //4:07.6480015 + 08:00","Animal":{"$type":"ConsoleApplication.Animal, ConsoleApp3","            //Name":"dog","Age":1}}            var baseObj = JsonConvert.DeserializeObject(json, settings);            Console.ReadKey();        }    }    class Animal    {        public string Name { get; set; }        public int Age { get; set; }    }    class BaseObj    {        public Animal Animal { get; set; }    }    class People : BaseObj    {        public DateTime StudentTime { get; set; }    }    class Dog : BaseObj    {        public DateTime EatTime { get; set; }    }    class ObjConverter : JsonConverter    {        public override bool CanConvert(Type objectType)        {            return typeof(BaseObj).IsAssignableFrom(objectType);        }        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)        {            JObject obj = JObject.Load(reader);            string type = (string)obj["$type"];            BaseObj baseObj;            if (type.Contains(nameof(People)))            {                baseObj = new People();            }            else            {                baseObj = new Dog();            }            serializer.Populate(obj.CreateReader(), baseObj);            if (baseObj.Animal == null)            {                baseObj.Animal = new Animal                {                    Name = (string)obj["ObjName"],                    Age = (int)obj["ObjAge"]                };            }            return baseObj;        }        public override bool CanWrite => false;        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)        {            throw new NotImplementedException();        }    }}