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

C# 实现动态扁平化嵌套JSON以适配DataGrid数据绑定的方案

嵌套JSON动态扁平化实现方案

需求说明

我们需要将任意层级嵌套的JSON结构自动展平为单层对象集合,适配DataGrid数据绑定场景,以下为样例参考:

  • 输入层级结构:Students -> Subjects -> Marks,每层均可包含多个子节点
  • 输出规则:最内层的子节点会向上合并所有父级的属性,生成单层JSON对象

输入样例

[
   {
      "student":"Bob",
      "subjects":[
         {
            "subjectname":"English",
            "marks":[
               {
                  "type":"essay",
                  "grade":"A"
               },
               {
                  "type":"vocabulary",
                  "grade":"B"
               },
               {
                  "type":"spoken",
                  "grade":"C"
               }
            ]
         },
         {
            "subjectname":"French",
            "marks":[
               {
                  "type":"essay",
                  "grade":"B"
               },
               {
                  "type":"vocabulary",
                  "grade":"A"
               },
               {
                  "type":"spoken",
                  "grade":"B"
               }
            ]
         }
      ]
   },
   {
      "student":"Mark",
      "subjects":[
         {
            "subjectname":"Dutch",
            "marks":[
               {
                  "type":"essay",
                  "grade":"C"
               },
               {
                  "type":"vocabulary",
                  "grade":"B"
               },
               {
                  "type":"spoken",
                  "grade":"A"
               }
            ]
         },
         {
            "subjectname":"Mandrian",
            "marks":[
               {
                  "type":"essay",
                  "grade":"C"
               },
               {
                  "type":"vocabulary",
                  "grade":"C"
               },
               {
                  "type":"spoken",
                  "grade":"C"
               }
            ]
         }
      ]
   }
]

预期输出

[
   {
      "student":"Bob",
      "subjectname":"English",
      "type":"essay",
      "grade":"A"
   },
   {
      "student":"Bob",
      "subjectname":"English",
      "type":"vocabulary",
      "grade":"B"
   },
   {
      "student":"Bob",
      "subjectname":"English",
      "type":"spoken",
      "grade":"C"
   },
   {
      "student":"Bob",
      "subjectname":"French",
      "type":"essay",
      "grade":"B"
   },
   {
      "student":"Bob",
      "subjectname":"French",
      "type":"vocabulary",
      "grade":"A"
   },
   {
      "student":"Bob",
      "subjectname":"French",
      "type":"spoken",
      "grade":"B"
   },
   ...
]

实现思路

原有代码的问题是没有处理数组生成多条结果的逻辑,会出现属性覆盖的问题,调整逻辑如下:

  1. 递归遍历JSON节点时维护当前已收集的父级属性集合
  2. 遇到数组节点时,遍历每一个子项,每个子项都单独复制一份当前父属性继续递归,避免不同数组项属性互相干扰
  3. 遇到叶子节点时直接写入当前属性集合,遍历到最内层无嵌套节点时,把完整对象加入结果集
  4. 不需要预设层级结构,支持任意层级的嵌套JSON自动展平

完整实现代码(C# 基于Newtonsoft.Json)

using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;

public static class JsonFlattener
{
    /// <summary>
    /// 嵌套JSON扁平化方法
    /// </summary>
    /// <param name="json">输入的嵌套JSON字符串</param>
    /// <returns>展平后的JSON数组字符串</returns>
    public static string Flatten(string json)
    {
        JToken input = JToken.Parse(json);
        List<JObject> result = new List<JObject>();
        ProcessToken(input, new JObject(), result);
        return JArray.FromObject(result).ToString();
    }

    private static void ProcessToken(JToken currentToken, JObject currentObj, List<JObject> result)
    {
        switch (currentToken.Type)
        {
            // 处理对象节点:遍历所有属性
            case JTokenType.Object:
                bool hasNestedChild = false;
                foreach (var prop in currentToken.Children<JProperty>())
                {
                    // 属性值为对象/数组时继续递归
                    if (prop.Value.Type is JTokenType.Object or JTokenType.Array)
                    {
                        hasNestedChild = true;
                        ProcessToken(prop.Value, currentObj, result);
                    }
                    // 叶子属性直接写入当前对象
                    else
                    {
                        // 若存在同名属性可自行调整为父级名+属性名的拼接逻辑避免覆盖
                        if (currentObj.ContainsKey(prop.Name))
                            currentObj[prop.Name] = prop.Value;
                        else
                            currentObj.Add(prop.Name, prop.Value);
                    }
                }
                // 无嵌套子节点说明是最内层对象,加入结果集
                if (!hasNestedChild)
                {
                    result.Add(new JObject(currentObj));
                }
                break;
            // 处理数组节点:每个子项复制当前属性集合单独递归
            case JTokenType.Array:
                foreach (var item in currentToken.Children())
                {
                    JObject newObj = new JObject(currentObj);
                    ProcessToken(item, newObj, result);
                }
                break;
        }
    }
}

使用说明

  • 直接调用JsonFlattener.Flatten(输入json字符串)即可得到展平后的JSON数组,可直接转为DataTable或者绑定到DataGrid
  • 无需预设JSON结构,支持任意层级的嵌套数组自动展开,适合封装到公共类库复用

内容的提问来源于stack exchange,提问作者Harsha kumar G H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:45:02