C# Newtonsoft.Json 解析多嵌套json 进行反序列化的实例
作者:蝶恋花雨 发布时间:2022-04-09 11:23:13
标签:C#,多嵌套,json,反序列化
我就废话不多说啦,大家还是直接看代码吧~
[
{
"orderNo": "3213123123123",
"time": "2016-09-09 12:23:33",
"orderStatus": "1",
"freeShipping": true,
"fullCut": 20,
"originalCost": 340,
"actualPayment": 320,
"goods": [
{
"UserId": "5",
"GoodsId": "8",
"Total": 40,
"Number": 2,
"ConCcoin": 0,
"PayMode": "支付宝",
"Price": "20.00",
"goodsImg": "UpLoadImg/GoodsImage/546fda6d-8417-4b8f-bac6-3084dca420a9.jpg",
"shopname": "两颗牙",
"goodsTitle": "周村烧饼",
"manmoney": "200",
"jianmoney": "20",
"jianyoufei": "8"
},
{
"UserId": "5",
"GoodsId": "7",
"Total": 60,
"Number": 1,
"ConCcoin": 0,
"PayMode": "支付宝",
"Price": "60.00",
"goodsImg": "UpLoadImg/GoodsImage/931be419-e9d3-4dae-ae93-5af619c217d9.jpg",
"shopname": "两颗牙",
"goodsTitle": "山东特产山东大枣1000g",
"manmoney": "200",
"jianmoney": "0",
"jianyoufei": "10"
}
]
}
]
上面为要解析的JSON数据
var json = "[{\"orderNo\": \"3213123123123\",\"time\": \"2016-09-09 12:23:33\",\"orderStatus\":\"1\", \"freeShipping\": true, \"fullCut\": 20,\"originalCost\": 340, \"actualPayment\": 320,\"goods\": [";
json += " {\"UserId\": \"5\",\"GoodsId\": \"8\", \"Total\": 40, \"Number\": 2, \"Price\": \"20.00\", \"shopname\": \"两颗牙\", \"manmoney\": \"200\", \"jianmoney\": \"0\",\"jianyoufei\": \"10\"},";
json += " {\"UserId\": \"5\",\"GoodsId\": \"7\", \"Total\": 60, \"Number\": 1, \"Price\": \"60.00\",\"shopname\": \"两颗牙\", \"manmoney\": \"200\", \"jianmoney\": \"0\",\"jianyoufei\": \"10\"},";
json += " ]} ]";
OrderDetails[] datas = JsonConvert.DeserializeObject<OrderDetails[]>(json);
List<OrderDetailsInsert> insert = new List<OrderDetailsInsert>();
foreach (OrderDetails data in datas)
{
var shopname = string.Empty;//判断是否同一个商家
foreach (var item in data.goods)
{
OrderDetailsInsert getinfo = new OrderDetailsInsert();
getinfo.orderno = data.orderno;
getinfo.time = data.time;
getinfo.orderStatus = data.orderStatus;
getinfo.actualPayment = data.actualPayment;
getinfo.orderno = data.orderno;
if (data.freeShipping == true)
{
getinfo.Remark = "此商品符合包邮条件及满" + item.manmoney + "减" + data.fullCut + "条件:订单总金额:" + data.originalCost + "符合满减条件减去:" + data.fullCut + "实际付款金额:" + data.actualPayment;
}
else if (!string.IsNullOrEmpty(data.fullCut.ToString()) && data.fullCut != 0)
{
getinfo.Remark = "此商品符合满" + item.manmoney + "减" + data.fullCut + "条件:订单总金额:" + data.originalCost + "符合满减条件减去:" + data.fullCut + "实际付款金额:" + data.actualPayment;
}
else
{
getinfo.Remark = "订单实际付款金额:" + data.actualPayment;
}
getinfo.GoodsId = item.GoodsId;
getinfo.Total = item.Total;
getinfo.Number = item.Number;
getinfo.Price = item.Price;
insert.Add(getinfo);
}
}
要用的对象类
public class OrderDetailsInsert
{
public string orderno { get; set; }
public DateTime time { get; set; }
public char orderStatus { get; set; }
public Decimal actualPayment { get; set; }
public int GoodsId { get; set; }
public string Total { get; set; }
public int Number { get; set; }
public string Price { get; set; }
public string Remark { get; set; }
}
public class OrderDetails
{
public string orderno { get; set; }
public DateTime time { get; set; }
public char orderStatus { get; set; }
public bool freeShipping { get; set; }
public Decimal fullCut { get; set; }
public Decimal originalCost { get; set; }
public Decimal actualPayment { get; set; }
public GoodsInfoList[] goods { get; set; }
}
public class GoodsInfoList
{
public int UserId { get; set; }
public int GoodsId { get; set; }
public string Total { get; set; }
public int Number { get; set; }
public string Price { get; set; }
public string shopname { get; set; }
public string manmoney { get; set; }
}
效果图:
补充:c#使用 Newtonsoft.Json 实现多态序列化
有时候会碰到以下情况
1.定义了一个类型为A的字段,但在实例化时使用的是它的派生类B。
2.定义了一个存储基类型A的集合,但实际上里面包含了各种各样的派生类。
上述两种情况在序列化的时候没有问题,但在反序列化的时候程序并不能将其转化为成派生类。
Newtonsoft.Json提供了一个JsonConverter特性,我们可以自定义某个数据的json读写方式以达成多态序列化的目的。
源码链接
1.自定义转化类
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
namespace XFramework.JsonConvter
{
/// <summary>
/// 用于多态列表的转化
/// </summary>
/// <typeparam name="T"></typeparam>
public class PolyListConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jObject = JObject.Load(reader);
List<T> values = new List<T>();
foreach (var item in jObject.Properties())
{
Type type = Type.GetType(item.Name);
var value = item.Value.ToObject(type);
values.Add((T)value);
}
return values;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var values = (List<T>)value;
JObject jObject = new JObject();
foreach (var item in values)
{
jObject.Add(item.GetType().FullName, JToken.FromObject(item));
}
var p = jObject.Properties();
foreach (var item in p)
{
Debug.Log(item.Name);
}
serializer.Serialize(writer, jObject);
}
}
/// <summary>
/// 用于多态序列化
/// </summary>
public class PolyConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jObject = JObject.Load(reader);
foreach (var item in jObject.Properties())
{
Type type = Type.GetType(item.Name);
var value = item.Value.ToObject(type);
return value;
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
JObject jObject = new JObject();
jObject.Add(value.GetType().FullName, JToken.FromObject(value));
serializer.Serialize(writer, jObject);
}
}
}
2.使用方式
DataBase是自己定义的一个数据基类,按照以下写法,再利用Newtonsoft 的API 序列化和反序列化TestData就可以成功实现多态读写了。
using XFramework.JsonConvter;
using Newtonsoft.Json;
public class TestData
{
// 对应第一种情况
[JsonConverter(typeof(PolyConverter))]
public DataBase datas;
// 对应第二种情况
[JsonConverter(typeof(PolyListConverter<DataBase>))]
public List<EquipPowerBase> powerList;
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
来源:https://blog.csdn.net/kongwei521/article/details/52488977


猜你喜欢
- Java虚拟机栈1. 定义栈:线程运行时需要的内存空间,一个栈存在多个栈帧。栈具有先入后出,后入先出的特点。栈帧:每个方法运行时需要的内存(
- 根据狂神的视频做的,然后自己优化了一些bug,比如新生成食物的时候不会生成在蛇的身体上,再新增长身体的时候不会在左上角出现一个绿色的方块以及
- Android 属性动画ValueAnimator与插值器详解一、ValueAnimator详解:ValueAnimator是整个动画的核心
- 单元测试单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,进而检查方法
- 文件名:page.xml<RelativeLayout xmlns:android="http://schemas.andr
- 刚刚看MSDN的一个例子无意发现的小技巧,大家一看就明白了,不过好像蛮有用的,先记下咯,以后慢慢研究。using System;namesp
- 关键词IDEA 如何控制编辑左侧的功能图标 ICONIDEA 左侧的图标不见了怎么恢复1、操作步骤依次打开 File | Settings
- 1.什么是结构化编程编程中只使用三大结构不能使用goto语句1972年美国科学家,发表论文证明所有的程序流程,只需要三大结构完成。2.为什么
- 本文实例为大家分享了Unity shader实现消融效果的具体代码,供大家参考,具体内容如下效果图:shader代码:// Upgrade
- 首先要引用一下类库:using Ionic.Zip;这个类库可以到网上下载。下面对类库使用的封装方法:得到指定的输入流的ZIP压
- 声明一个客户端对象:protected RedisClient Redis = new RedisClient("127.0.0
- Android TimePicker 直接输入的问题解决方案TimePicker 提供了上下的按钮,点击按钮,相关操作都是正常的。但是如果直
- 最近有一个需求是选择多级联动数据,数据级别不固定,可能是五级,可能是两级,具体看用户等级。所以就需要一个多级联动选择控件 ,在网上一番搜索或
- 一、基本特点1. 开始时是乐观锁, 如果锁冲突频繁, 就转换为悲观锁.2. 开始是轻量级锁实现, 如果锁被持有的时间较长, 就转换成重量级锁
- 1. 什么是局部类型?C# 2.0 引入了局部类型的概念。局部类型允许我们将一个类、结构或接口分成几个部分,分别实现在几个不同的.cs文件中
- 本文介绍MediaPlayer的使用。MediaPlayer可以播放音频和视频,另外也可以通过VideoView来播放视频,虽然VideoV
- webservice 可以用于分布式应用程序之间的交互,和不同程序之间的交互。概念性的东西就不说太多,下面开始创建一个简单的webservi
- 今天在编译Java程序时遇到如下问题:No enclosing instance of type PrintListFromTailToHe
- 强调一下阅读系统源码,起码要对进程间通信要了解,对binder机制非常非常清楚,binder就是指南针,要不然你会晕头转向;强行阅读,就容易
- 关于[Cannot determine value type from string ‘xxx’]的