C# Newtonsoft.Json 解析多巢狀json 進行反序列化的例項
阿新 • • 發佈:2021-01-14
我就廢話不多說啦,大家還是直接看程式碼吧~
[ { "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,"Price": "60.00","goodsImg": "UpLoadImg/GoodsImage/931be419-e9d3-4dae-ae93-5af619c217d9.jpg","goodsTitle": "山東特產山東大棗1000g","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\","; 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,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,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; }
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。