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. Joomla软件功能介绍与开源程序大比拼Joomla,wordpress,Drupal哪个好?

    Joomla 软件功能介绍:    Joomla!是一套在国外相当知名的内容管理系统 (Content Management System, CMS),它属于Portal(企业入口网站)类型,顾名思义 ...

  2. ios基础篇(二十六)—— UITableViewCell的分组索引与标记

    一.表视图的索引目录 首先要创建一个TableView,之前有说过,这里就不详细说了(参考前面第十四篇). 直接贴代码吧, #import "ViewController.h" @ ...

  3. oracle initialization or shutdown in progress解决方法

    [解决方法]   SQL> connect sys/hope as sysdba 已连接. SQL> shutdown normal ORA-01109: 数据库未打开     已经卸载数 ...

  4. deepin linux字体渲染(转)

    <?xml version='1.0'?> <!DOCTYPE fontconfig SYSTEM 'fonts.dtd'> <fontconfig> <ma ...

  5. Java期末设计(十三周)

    一.项目完成计划     十三周和十四周完成用户交互界面的设计(1.登陆界面2.订票以及查询界面3.用户管理界面4.退票界面):     十三周完成登陆界面,十四周完成订票以及查询界面,用户管理界面和 ...

  6. 用JS修改checkbox的选中状态

    代码如下: <SCRIPT LANGUAGE="JavaScript"> <!-- function change() { var c=document.myfo ...

  7. mac 端口被占用及kill端口

    在本地部署 Web 应用时我有遇到过某网络端口已经被其他程序占用的情况,这时候就需要先退出占用该端口的进程,我们可以通过“终端”来实现结束占用某特定端口的进程 1.打开终端,使用如下命令: lsof ...

  8. 4、jvm内存回收——器

    内存回收---->垃圾回收---->GC GC 三基础,一个综合G1 串行:单线程,回收暂停其他 并行:多线程,回收暂停其他 并发:多线程,回收不暂停?! 成功好说,失败Serial Ol ...

  9. Unity3D之GUITexture的坐标体系

    Unity3D的GUITexture的坐标,其中x和y的取值在0~1之间,层次使用z来划分,值越大越靠前.

  10. Dom学习笔记

    今天老师出了一道面试题目:取到表单里面的textbox的值,两种方法.知道一种,老师说的什么dom,我竟然不知道. 以前学html的时候,老师也重来没有提到dom的概念.javaScript只是学了一 ...