如何更简单地反序列化JSON数组,跳过外层result直接提取dataset数据
解决方案
方案1:直接用JToken解析,无需定义外层冗余DTO
不需要定义OE_GetActiveSubGroupsResultDTO、OE_GetSubActiveGroupsListDTO两个外层DTO类,直接按JSON路径提取目标节点即可,同时可以删掉原代码中冗余的二次反序列化逻辑:
using Newtonsoft.Json.Linq; public ActionResult ProcessSpareParts(CarViewModel vm) { // 直接解析原始JSON为JObject var jsonObj = JObject.Parse(GetActiveSubGroups); // 直接定位到dataset节点,转成强类型列表 var datasetList = jsonObj["result"][1]["dataset"].ToObject<List<OE_GetActiveSubGroupsDTO>>(); foreach(var item in datasetList) { // 直接使用强类型对象item即可,无需二次反序列化 // 你的原有业务逻辑... } }
优势:
- 砍掉2层冗余DTO定义,代码量直接减少近一半
- 避免了原代码中
ToString()后二次反序列化的性能损耗和潜在异常 - 逻辑直观,直接按JSON结构取需要的节点
方案2:封装通用扩展方法,适配所有同格式接口
如果所有API返回都是同样的JSON结构,可以把提取逻辑封装成通用扩展方法,一劳永逸:
public static class JsonApiExtension { /// <summary> /// 从统一格式的API返回JSON中直接提取dataset集合 /// </summary> /// <typeparam name="T">dataset内的元素类型</typeparam> /// <param name="jsonStr">接口返回的原始JSON字符串</param> /// <returns>dataset对应的强类型列表</returns> public static List<T> ExtractDataset<T>(this string jsonStr) { var jObj = JObject.Parse(jsonStr); var resultArr = jObj["result"] as JArray; // 可根据业务需要添加空校验、异常抛出逻辑 if (resultArr == null || resultArr.Count < 2 || resultArr[1]["dataset"] == null) { return new List<T>(); } return resultArr[1]["dataset"].ToObject<List<T>>(); } }
调用时仅需一行代码:
public ActionResult ProcessSpareParts(CarViewModel vm) { var datasetList = GetActiveSubGroups.ExtractDataset<OE_GetActiveSubGroupsDTO>(); foreach(var item in datasetList) { // 原有业务逻辑 } }
优势:
- 所有同格式接口都可以复用该方法,无需重复写解析逻辑
- 后续如果接口格式调整,仅需要修改一次扩展方法即可,维护成本极低
内容的提问来源于stack exchange,提问作者staff614
相关产品推荐
相关产品推荐

