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

如何将API返回JSON的OptionSets/OptionSetsClean反序列化为字典或列表?

解决JSON反序列化中OptionSetsClean和OptionSets字段的转换问题

问题分析

API返回的JSON里,OptionSetsClean是JSON字符串格式的键值对数组,而OptionSets是由单个键值对对象组成的数组。你当前定义的GetJsonResult类无法正确将这两个字段转换为Dictionary或List类型,原因如下:

  • OptionSets字段:用object类型接收无法自动解析为结构化集合,实际结构是List<Dictionary<string, int>>(每个元素是仅有一个键值对的字典)。
  • OptionSetsClean字段:它本身是字符串类型的JSON,直接声明为Dictionary<string, int>会反序列化失败,因为字符串无法直接映射为字典,需要先解析字符串再二次反序列化。

解决方案

1. 修改GetJsonResult类定义

针对两个字段的特性,调整类型并添加自动转换逻辑:

using Newtonsoft.Json;
using System.Linq;

// 匹配API外层结构的根类
public class RootResult
{
    [JsonProperty("GetJsonResult")]
    public GetJsonResult GetJsonResult { get; set; }
}

public class GetJsonResult
{
    [JsonProperty("EntityName")]
    public string EntityName { get; set; }

    [JsonProperty("FailureReason")]
    public string FailureReason { get; set; }

    [JsonProperty("Counter")]
    public int Counter { get; set; }

    [JsonProperty("MoreRecords")]
    public bool MoreRecords { get; set; }

    [JsonProperty("OptionSetName")]
    public string? OptionSetName { get; set; }

    [JsonProperty("Success")]
    public bool Success { get; set; }

    // 私有字段接收原始字符串,对外提供转换后的字典
    [JsonProperty("OptionSetsClean")]
    private string OptionSetsCleanRaw { get; set; }
    
    public Dictionary<string, int>? OptionSetsClean
    {
        get
        {
            if (string.IsNullOrEmpty(OptionSetsCleanRaw)) return null;
            // 先解析字符串为单键字典数组,再合并为完整字典
            var singleDictList = JsonConvert.DeserializeObject<List<Dictionary<string, int>>>(OptionSetsCleanRaw);
            return singleDictList?.SelectMany(d => d).ToDictionary(kv => kv.Key, kv => kv.Value);
        }
    }

    // 直接用List<Dictionary<string, int>>接收OptionSets数组
    [JsonProperty("OptionSets")]
    public List<Dictionary<string, int>>? OptionSets { get; set; }

    // 可选:提供合并后的字典属性,方便直接使用OptionSets的数据
    public Dictionary<string, int>? MergedOptionSets
    {
        get => OptionSets?.SelectMany(d => d).ToDictionary(kv => kv.Key, kv => kv.Value);
    }

    [JsonProperty("Entities")]
    public object? Entities { get; set; }
}

2. 反序列化代码示例

直接调用JsonConvert.DeserializeObject即可,类内部已处理转换逻辑:

string apiResponseJson = "你的API返回完整JSON字符串";
var rootData = JsonConvert.DeserializeObject<RootResult>(apiResponseJson);
var result = rootData.GetJsonResult;

// 访问转换后的字典
var cleanOptionDict = result.OptionSetsClean;
var mergedOptionDict = result.MergedOptionSets;

3. 替代方案:用自定义JsonConverter处理OptionSetsClean

如果不想用私有字段+计算属性的方式,可以给OptionSetsClean添加自定义转换器:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Linq;

public class StringToMergedDictConverter : JsonConverter<Dictionary<string, int>>
{
    public override Dictionary<string, int>? ReadJson(JsonReader reader, Type objectType, Dictionary<string, int>? existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.String)
        {
            var jsonStr = (string)reader.Value;
            var singleDictList = JsonConvert.DeserializeObject<List<Dictionary<string, int>>>(jsonStr);
            return singleDictList?.SelectMany(d => d).ToDictionary(kv => kv.Key, kv => kv.Value);
        }
        return serializer.Deserialize<Dictionary<string, int>>(reader);
    }

    public override void WriteJson(JsonWriter writer, Dictionary<string, int>? value, JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }
        // 序列化时转回原格式的JSON字符串
        var singleDictList = value.Select(kv => new Dictionary<string, int> { { kv.Key, kv.Value } }).ToList();
        writer.WriteValue(JsonConvert.SerializeObject(singleDictList));
    }
}

然后在类中应用转换器:

[JsonProperty("OptionSetsClean")]
[JsonConverter(typeof(StringToMergedDictConverter))]
public Dictionary<string, int>? OptionSetsClean { get; set; }

关键说明

  • OptionSets的JSON结构是多个单键值对对象的数组,必须用List<Dictionary<string, int>>接收,直接用Dictionary会反序列化失败。
  • OptionSetsClean是嵌套的JSON字符串,必须先解析字符串得到数组,再合并为单个Dictionary,因为原字符串内容是数组格式而非单个字典。

内容的提问来源于stack exchange,提问作者GordonS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:20:14