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

在C# .NET Core中反序列化含字典与固定字段的复杂JSON

.NET Core中正确反序列化含动态键与固定字段的JSON数据

问题分析

你提供的JSON数据中,performances数组的每个元素混合了动态键(如Employee1、Employee2)和固定字段(starttime、endtime)。原类结构因字段映射错误导致反序列化后所有值为null;直接用Dictionary<string, Employee>又无法兼容固定字段,需要调整类结构来同时处理这两种类型的字段。

解决方案

利用JsonExtensionData特性(System.Text.Json或Newtonsoft.Json均支持)接收动态键,同时保留固定字段的强类型映射,是适配这种JSON结构的最优方式。

方案1:使用System.Text.Json(.NET Core内置)

修正后的类定义

using System.Text.Json.Serialization;

public class Variable
{
    public string firstname { get; set; }
    public double value { get; set; }
}

public class PerformanceItem
{
    // 接收所有动态的EmployeeX字段,暂存为JsonElement
    [JsonExtensionData]
    public Dictionary<string, JsonElement> EmployeeRawData { get; set; }
    
    // 固定字段
    public string starttime { get; set; }
    public string endtime { get; set; }

    // 便捷属性:将JsonElement转换为强类型Variable
    public Dictionary<string, Variable> Employees
    {
        get
        {
            if (EmployeeRawData == null) return null;
            return EmployeeRawData.ToDictionary(
                kvp => kvp.Key,
                kvp => JsonSerializer.Deserialize<Variable>(kvp.Value.GetRawText())
            );
        }
    }
}

public class PerformanceList
{
    public List<PerformanceItem> performances { get; set; }
}

反序列化代码

// 假设jsonString是从API获取的JSON字符串
var result = JsonSerializer.Deserialize<PerformanceList>(jsonString);

// 示例:遍历数据
foreach (var period in result.performances)
{
    Console.WriteLine($"时间范围:{period.starttime} → {period.endtime}");
    foreach (var emp in period.Employees)
    {
        Console.WriteLine($"{emp.Key}: 姓名={emp.Value.firstname},数值={emp.Value.value}");
    }
}

方案2:使用Newtonsoft.Json(Json.NET)

Newtonsoft.Json的JsonExtensionData支持直接将动态键反序列化为强类型,无需额外转换:

修正后的类定义

using Newtonsoft.Json;

public class Variable
{
    public string firstname { get; set; }
    public double value { get; set; }
}

public class PerformanceItem
{
    // 直接将动态EmployeeX字段反序列化为Dictionary<string, Variable>
    [JsonExtensionData]
    public Dictionary<string, Variable> Employees { get; set; }
    
    // 固定字段
    public string starttime { get; set; }
    public string endtime { get; set; }
}

public class PerformanceList
{
    public List<PerformanceItem> performances { get; set; }
}

反序列化代码

var result = JsonConvert.DeserializeObject<PerformanceList>(jsonString);

原代码失败原因

  • 原Custom类中的response字段是List<Dictionary<string, Variable>>,但JSON里每个performances元素并没有名为response的数组,而是直接在对象中包含动态键和固定字段,结构完全不匹配,导致反序列化时无法映射任何值。
  • 直接使用Dictionary<string, Employee>会把starttime、endtime也当作动态键处理,无法区分固定字段,不符合业务需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:32:21