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 = ,
Demos = new List<DemoBase>()
{
new DemoA() {Id=, Name="demoA", Type="A",Color="red" },
new DemoB() {Id=, Name="", Type="B",Size= new double[]{ ,} }
}
}; 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

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

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

    使用Newtonsoft.Json 转换DateTime类型时,若使用标准转换,则字符串内会有一个T(虽然再转换成DateTime没有问题). 若要转换成DateTime没有T,可以加上特性: pub ...

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

    Json.Net是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更加简单.通过Linq To JSON可以快速的读写Json,通过JsonSerializ ...

  3. Newtonsoft.Json序列化Enum类型

    [JsonConverter(typeof(StringEnumConverter))] public StringAlignment TextAlign { get => textAlign; ...

  4. 利用Newtonsoft.Json实现Json序列化与反序列化

    在项目中用到了Newtonsoft.Json来实现序列化和反序列化,在这里写下实现代码. 1.创建类用于排除不序列化的属性 public class ExcludePropertiesContract ...

  5. Newtonsoft.Json 的基本用法

    Ø  前言 说起 C# 对 JSON 的操作(序列化与反序列化),大家都会想到 JavaScriptSerializer.DataContractJsonSerializer 与 Newtonsoft ...

  6. C# dynamic类型序列化和反序列化之Newtonsoft.Json,动态解析远端返回的jSON数据

    一.说明 1.Newtonsoft.Json 中的Linq To Json中提供了方便的json数据查询.修改等操作. 例如:JObject,JArray 2.在JObject.FromObject( ...

  7. 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型;

    导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型:    二:C#对象.集合.DataTable与Json内容互转示例: ...

  8. Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解

    Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全   Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...

  9. C# dynamic类型序列化和反序列化之Newtonsoft.Json

    原文:C# dynamic类型序列化和反序列化之Newtonsoft.Json 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u011127019/ ...

随机推荐

  1. ios基础篇(二十七)—— Json解析

    一.什么是Json JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. JSON采用完全独立于语言的文本格式,但是也使 ...

  2. java selenium (十三) 智能等待页面加载完成

    我们经常会碰到用selenium操作页面上某个元素的时候, 需要等待页面加载完成后, 才能操作.  否则页面上的元素不存在,会抛出异常. 或者碰到AJAX异步加载,我们需要等待元素加载完成后, 才能操 ...

  3. android回收AnimationDrawable动画的每一帧的图片资源,而释放内存

    回收每一帧的图片,释放内存资源 private void tryRecycleAnimationDrawable(AnimationDrawable animationDrawables) { if ...

  4. JavaEE MyBatis

    1.  简介 MyBatis本是apache的一个开源项目iBatis的升级版,2013年11月迁移到Github,是三层架构中持久层框架. 目前提供了Java..NET.以及Ruby三种语言实现的版 ...

  5. CSS各类标签用法——选择器

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  6. hadoop输入分片计算(Map Task个数的确定)

    作业从JobClient端的submitJobInternal()方法提交作业的同时,调用InputFormat接口的getSplits()方法来创建split.默认是使用InputFormat的子类 ...

  7. 转别人的 STM32外部中断使用注意事项

    前言:这些问题都是我之前在工作中遇到的,后来觉得需要总结,自己记忆不好,所以在这个给自己打个mark. 一:触发方式 STM32 的外部中断是通过边沿来触发的,不支持电平触发: 二:外部中断分组 ST ...

  8. Tomcat内存优化参数

    set JAVA_OPTS=-Xms512m -Xmx512m -XX:PermSize=128M -XX:MaxNewSize=128m -XX:MaxPermSize=128m 在catalina ...

  9. C#操作PPT表格

    1.激活组件 AxFramerControl改控件的dll自己再网上百度下下载这里不多讲 /// <summary>        /// 检测是否注册控件        /// < ...

  10. asp.net初识

    请求=========处理=============响应 不是服务器读网页.表单,而是我们向服务器提交数据 1.asp.net 服务器端控件是ASP.NET对HTML的封装,ASP.NET会将服务器端 ...