You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 18:05:18