C#中如何将JSON对象转为数组以简化反序列化操作?
问题描述
调用API返回的JSON数据中,result字段是一个键为提供商名称(数量和名称不固定)、值为同类型数组的JSON对象。需要保留这些提供商名称,目前采用Dictionary<string, List<ProviderModel>>反序列化后通过SelectMany展平的方案较为繁琐,希望直接将result转换为JSON数组,从而反序列化为List<ProviderModel>。
示例JSON结构:
{ "status": "ok", "result": { "firstprovider": [ .... ], "secondprovider": [ ...], "thirdprovider": [ ... ] } }
当前实现代码(简化版):
string json = "{\r\n\"status\": \"ok\", \r\n\"result\": { \r\n \"firstprovider\": [ {\"name\":\"John\"}, {\"car\":\"BMW\"}, {\"surname\":\"Johnson\", \"age\":30, \"car\":\"fast\"} ],\r\n \"secondprovider\": [ {\"name\":\"Zoe\"}, {\"car\":\"Ford\"}, {\"surname\":\"johnsøn\", \"age\":31, \"car\":null}], \r\n \"thirdprovider\": [{\"name\":\"Elliot\"}, {\"car\":\"Volkswagen\"}, {\"surname\":\"Jackson\", \"age\":32, \"car\":null} ] \r\n }\r\n }\r\n"; // 反序列化为Dictionary var resultDict = JsonConvert.DeserializeObject<ResultModel>(json); // 展平为列表(此部分繁琐) var providerModelList = resultDict.result.SelectMany(listOfEvents => { listOfEvents.Value.Select(Provider => { Provider.provider = listOfEvents.Key; return Provider; }).ToList(); return listOfEvents.Value; }).ToList(); public class ResultModel { [JsonProperty("result")] public Dictionary<string, List<ProviderModel>> result { get; set; } } public class ProviderModel { public string provider { get; set; } public string name { get; set; } public string surname { get; set; } }
期望的ResultModel结构:
public class ResultModel { [JsonProperty("result")] public List<ProviderModel> result { get; set; } }
解决方案
方法一:自定义JsonConverter
通过实现JsonConverter,在反序列化过程中直接将result的对象结构转换为目标列表,并自动填充provider字段。
代码实现:
public class ProviderListConverter : JsonConverter<List<ProviderModel>> { public override List<ProviderModel> ReadJson(JsonReader reader, Type objectType, List<ProviderModel> existingValue, bool hasExistingValue, JsonSerializer serializer) { var providerObj = JObject.Load(reader); var providerList = new List<ProviderModel>(); foreach (var prop in providerObj.Properties()) { var providerName = prop.Name; var items = prop.Value.ToObject<List<ProviderModel>>(); foreach (var item in items) { item.provider = providerName; providerList.Add(item); } } return providerList; } public override void WriteJson(JsonWriter writer, List<ProviderModel> value, JsonSerializer serializer) { // 若无需序列化回原格式,可抛出异常或留空 throw new NotImplementedException(); } }
修改ResultModel,为result字段添加转换器特性:
public class ResultModel { [JsonProperty("result")] [JsonConverter(typeof(ProviderListConverter))] public List<ProviderModel> result { get; set; } } public class ProviderModel { public string provider { get; set; } public string name { get; set; } public string surname { get; set; } // 按需添加其他字段如car、age }
使用时直接反序列化即可:
var result = JsonConvert.DeserializeObject<ResultModel>(json); // result.result即为已填充provider字段的List<ProviderModel>
方法二:基于JObject手动转换
如果不想编写自定义转换器,可以先将JSON解析为JObject,手动遍历result属性生成目标列表:
var jObj = JObject.Parse(json); var resultObj = jObj["result"] as JObject; var providerList = new List<ProviderModel>(); foreach (var prop in resultObj.Properties()) { var items = prop.Value.ToObject<List<ProviderModel>>(); foreach (var item in items) { item.provider = prop.Name; providerList.Add(item); } } // 如需封装到ResultModel var resultModel = new ResultModel { result = providerList };
内容的提问来源于stack exchange,提问作者penstiaGarse
相关产品推荐
相关产品推荐

