Newtonsoft.Json 处理多态类型的反序列化

Newtonsoft.Json的序列化和反序列化很成熟也很好用, 最近在处理多态类型的反序列化中遇到了问题, 反序列化后只能到基类,而得不到也不能转换到子类。从网上查询了一番后,需要写一个创建类型的Converter, 下面我们一步一步来:

1. 首先说明类型的定义, 为了做这个实验,我定义了一个基类和两个子类, 然后我要序列化的对象包含了这个基类的集合。

namespace LexSry
{
    using Newtonsoft.Json;
    using System.Collections.Generic;
    class DemoData
    {
        [JsonProperty("demoId")]
        public int DemoId { get; set; }

        [JsonProperty("demos")]
        public List<DemoBase> Demos { get; set; }
    }

    public class DemoBase
    {
        [JsonProperty("id")]
        public int Id { get; set; }
        [JsonProperty("name")]
        public string Name { get; set; }
        [JsonProperty("type")]
        public string Type { get; set; }
    }

    public class DemoA : DemoBase
    {
        [JsonProperty("color")]
        public string Color { get; set; }

    }

    public class DemoB: DemoBase
    {
        [JsonProperty("size")]
        public double[] Size { get; set; }
    }
}

2. 序列化,反序列化方法。反序列化时使用 JsonConvert.DeserializeObject<T>(string value, param JsonConverter[] converter)。 通过自己定义JsonConverter来实现创建相应的子类。

在本演示中, 我首先创建了抽象类 JsonCreationConverter<T>:JsonConverter ,

其次, 针对于DemoBase的解析, 我创建了 JsonDemoConverter:JsonCreationConverter<DemoBase>

    class JsonParser3
    {
        public static void WriteJson(object t, string file)
        {
            JsonSerializer serializer = new JsonSerializer();
            using (StreamWriter sw = new StreamWriter(file))
            {
                using (JsonWriter writer = new JsonTextWriter(sw))
                {
                    serializer.Serialize(writer, t);
                }
            }
        }

        public static void ReadJson<T>(string file, out T obj)
        {
            JsonSerializer serializer = new JsonSerializer();
            using (StreamReader sr = new StreamReader(file))
            {
                obj = JsonConvert.DeserializeObject<T>(sr.ReadToEnd(),new JsonDemoConverter());
            }
        }
    }

    public abstract class JsonCreationConverter<T>:JsonConverter
    {
        protected abstract T Create(Type objectType, JObject jsonObject);
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jsonObject = JObject.Load(reader);
            var target = Create(objectType, jsonObject);
            serializer.Populate(jsonObject.CreateReader(), target);
            return target;
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }

    public class JsonDemoConverter:JsonCreationConverter<DemoBase>
    {
        protected override DemoBase Create(Type objectType, JObject jsonObject)
        {
            var typeName = jsonObject["type"].ToString();
            switch(typeName)
            {
                case "A":
                    return new DemoA();
                case "B":
                    return new DemoB();
                default: return null;
            }
        }
    }
}

3. 在代码中实现将内存中的对象序列化到test.json中, 然后,从test.json中将数据反序列化到内存对象nData:

            DemoData data = new DemoData()
            {
                DemoId = 1,
                Demos = new List<DemoBase>()
                {
                    new DemoA() {Id=1, Name="demoA", Type="A",Color="red" },
                    new DemoB() {Id=2, Name="", Type="B",Size= new double[]{ 10,10} }
                }
            };

            JsonParser3.WriteJson(data, "test.json");

            DemoData nData = new DemoData();
            JsonParser3.ReadJson<DemoData>("test.json", out nData);

4. test.json中的数据:

{
  "demoId": 1,
  "demos": [
    {
      "color": "red",
      "id": 1,
      "name": "demoA",
      "type": "A"
    },
    {
      "size": [ 10.0, 10.0 ],
      "id": 2,
      "name": "",
      "type": "B"
    }
  ]
}

5. 反序列化后, 内存中得到的对象nData

时间: 2024-10-06 19:20:26

Newtonsoft.Json 处理多态类型的反序列化的相关文章

Newtonsoft.Json 转换DateTime类型为字符串时,串内部会有一个T。解决方案

使用Newtonsoft.Json 转换DateTime类型时,若使用标准转换,则字符串内会有一个T(虽然再转换成DateTime没有问题). 若要转换成DateTime没有T,可以加上特性: 1 public class TestClass 2 { 3 public TestClass() 4 { 5 Dt1 = Dt2 = new DateTime(1900, 1, 1, 0, 0, 0); 6 } 7 8 [JsonConverter(typeof(TcDateTimeConverter)

C# 使用Newtonsoft.Json序列化自定义类型

Json.Net是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Linq To JSON可以快速的读写Json,通过JsonSerializer可以序列化你的.Net对象. 让你轻松实现.Net中所有类型(对象,基本数据类型等)和Json的转换. 官网上三种不同的组件性能对比 /****************************************************************** * 创建人:HTL * 创

.Net使用Newtonsoft.Json.dll(JSON.NET)对象序列化成json、反序列化json示例教程

JSON作为一种轻量级的数据交换格式,简单灵活,被很多系统用来数据交互,作为一名.NET开发人员,JSON.NET无疑是最好的序列化框架,支持XML和JSON序列化,高性能,免费开源,支持LINQ查询.目前已被微软集成于webapi框架之中,因此,熟练掌握JSON.NET相当重要,这篇文章是零度参考官网整理的示例,通过这些示例,可以全面了解JSON.NET提供的功能. Newtonsoft.Json的地址: 官网:http://json.codeplex.com/ 源码地址:https://gi

使用Newtonsoft.Json.dll(JSON.NET)动态解析JSON、.net 的json的序列化与反序列化(一)

在开发中,我非常喜欢动态语言和匿名对象带来的方便,JSON.NET具有动态序列化和反序列化任意JSON内容的能力,不必将它映射到具体的强类型对象,它可以处理不确定的类型(集合.字典.动态对象和匿名对象),在这篇文章中我将通过JToken.JObject和JArray来动态解析JSON对象,使它很容易创建和检索的JSON内容而无需基础类型.通过JObject和JArray创建JSON对象我们先用非常简单的方法来动态创建一些JSON,可通过JToken派生的JSON.NET对象来进行,最常见的JTo

Newtonsoft.Json 的序列化与反序列化

转自:http://www.cnblogs.com/08shiyan/p/3464028.html 首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我举例说明DataTable的序列化和反序列化.创建一个DataTable对象,如下: DataTable dt = new DataTable(); DataColumn dcName = new DataColumn("Name"); Da

使用JSON.Net(Newtonsoft.Json)作为ASP.Net MVC的json序列化和反序列化工具

ASP.Net MVC默认的JSON序列化使用的是微软自己的JavaScriptSerializer.性能低不说,最让人受不了的是Dictionary<,>和Hashtable类型居然对应的json是[{"Key":"a","Value":1}]而不是{"a":1}.真是奇葩到家了,跟前端根本没法集成! 决定还是用JSON.Net来做吧!查了各种资料,网上的要么代码太复杂,要么没法完全实现.又在ILSpy分析了MV

Newtonsoft.Json 序列化和反序列化 时间格式【转】

1.JSON序列化 string JsonStr= JsonConvert.SerializeObject(Entity); eg: A a=new A(); a.Name="Elain00"; a.Hobby="eat eat"; string jsonStr=JsonConvert.SerializeObject(a); 2.JSON反序列化 string jsonstr = "jsonString";Class model = JsonCo

newtonsoft.json 序列化,反序列化

public class Book { public string BookID { get; set; } public DateTime PublishDate { get; set; } public decimal Price { get; set; } public override string ToString() { return "ID:" + BookID + "; Date:" + PublishDate.ToShortDateString()

Newtonsoft.Json 序列化和反序列化 时间格式

1.JSON序列化 string JsonStr= JsonConvert.SerializeObject(Entity); eg: A a=new A(); a.Name="Elain00"; a.Hobby="eat eat"; string jsonStr=JsonConvert.SerializeObject(a); 2.JSON反序列化 string jsonstr = "jsonString";Class model = JsonCo