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

如何在C# .NET中解析结构不固定的JSON数据?

C# .NET解析动态Key JSON的最佳方式

你的JSON特点是data字段下的键是动态数字,且子对象的属性不固定,没法直接用强类型模型映射,推荐以下几种实用方案:

方案1:使用.NET内置的System.Text.Json

适合.NET Core 3.0+、.NET 5+版本,无需额外安装包:

实现步骤:

  1. 按行拆分输入的JSON内容(因为示例是多行独立JSON结构)
  2. 用JsonNode(灵活的动态JSON节点)或Dictionary<string, JsonElement>解析每行内容

示例代码:

using System.Text.Json;
using System.Text.Json.Nodes;

// 假设你的JSON内容是多行字符串
string jsonContent = @"{""data"":{""5"":{""isDeleted"":""false"",""day"":""THU""}},""action"":""edit""}
{""data"":{""7"":{""isDeleted"":""false"",""name"":""alex""}},""action"":""edit""}
{""data"":{""90"":{""isDeleted"":""true"",""job"":""software""}},""action"":""edit""}";

// 按行拆分并过滤空行
string[] jsonLines = jsonContent.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

foreach (string line in jsonLines)
{
    // 解析为可动态访问的JsonNode
    JsonNode root = JsonNode.Parse(line)!;
    
    // 获取固定的action字段
    string action = root["action"]!.GetValue<string>();
    
    // 遍历data下的动态key
    JsonNode dataNode = root["data"]!;
    foreach (var kvp in dataNode.AsObject())
    {
        string dynamicKey = kvp.Key; // 对应"5"、"7"、"90"这类动态键
        JsonNode item = kvp.Value;
        
        // 获取公共字段isDeleted
        string isDeleted = item["isDeleted"]!.GetValue<string>();
        
        // 按需获取其他动态字段
        if (item["day"] is not null)
        {
            string day = item["day"]!.GetValue<string>();
            Console.WriteLine($"动态键: {dynamicKey}, 操作: {action}, 是否删除: {isDeleted}, 星期: {day}");
        }
        else if (item["name"] is not null)
        {
            string name = item["name"]!.GetValue<string>();
            Console.WriteLine($"动态键: {dynamicKey}, 操作: {action}, 是否删除: {isDeleted}, 姓名: {name}");
        }
        else if (item["job"] is not null)
        {
            string job = item["job"]!.GetValue<string>();
            Console.WriteLine($"动态键: {dynamicKey}, 操作: {action}, 是否删除: {isDeleted}, 职业: {job}");
        }
    }
}

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

如果项目已经依赖这个第三方库,用它处理动态结构会更简洁:

示例代码:

using Newtonsoft.Json.Linq;

string jsonContent = @"{""data"":{""5"":{""isDeleted"":""false"",""day"":""THU""}},""action"":""edit""}
{""data"":{""7"":{""isDeleted"":""false"",""name"":""alex""}},""action"":""edit""}
{""data"":{""90"":{""isDeleted"":""true"",""job"":""software""}},""action"":""edit""}";

string[] jsonLines = jsonContent.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

foreach (string line in jsonLines)
{
    JObject root = JObject.Parse(line);
    string action = root["action"]!.Value<string>();
    
    JObject dataObj = (JObject)root["data"]!;
    foreach (var kvp in dataObj)
    {
        string dynamicKey = kvp.Key;
        JToken item = kvp.Value;
        
        string isDeleted = item["isDeleted"]!.Value<string>();
        
        if (item["day"] != null)
        {
            string day = item["day"].Value<string>();
            Console.WriteLine($"动态键: {dynamicKey}, 操作: {action}, 是否删除: {isDeleted}, 星期: {day}");
        }
        else if (item["name"] != null)
        {
            string name = item["name"].Value<string>();
            Console.WriteLine($"动态键: {dynamicKey}, 操作: {action}, 是否删除: {isDeleted}, 姓名: {name}");
        }
        else if (item["job"] != null)
        {
            string job = item["job"].Value<string>();
            Console.WriteLine($"动态键: {dynamicKey}, 操作: {action}, 是否删除: {isDeleted}, 职业: {job}");
        }
    }
}

方案3:强类型+动态字典结合

如果isDeleted是固定公共字段,其他字段动态,可以用这种方式兼顾类型安全和灵活性:

using System.Text.Json;

// 定义包含公共字段的模型,用字典存动态字段
public class BaseDataItem
{
    public string isDeleted { get; set; }
    [JsonExtensionData]
    public Dictionary<string, JsonElement> ExtraFields { get; set; } = new();
}

public class JsonRoot
{
    public Dictionary<string, BaseDataItem> data { get; set; }
    public string action { get; set; }
}

// 解析示例
string sampleLine = @"{""data"":{""5"":{""isDeleted"":""false"",""day"":""THU""}},""action"":""edit""}";
JsonRoot root = JsonSerializer.Deserialize<JsonRoot>(sampleLine)!;

foreach (var kvp in root.data)
{
    string dynamicKey = kvp.Key;
    BaseDataItem item = kvp.Value;
    
    Console.WriteLine($"动态键: {dynamicKey}, 操作: {root.action}, 是否删除: {item.isDeleted}");
    // 尝试获取动态字段day
    if (item.ExtraFields.TryGetValue("day", out JsonElement dayElem))
    {
        string day = dayElem.GetString()!;
        Console.WriteLine($"星期: {day}");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:20:30