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

C#将嵌套JSON转为扁平Dictionary<string,string>求助(Newtonsoft.Json无效)

解决JSON扁平化为Dictionary<string, string>的方案

别担心,Newtonsoft.Json(Json.NET)完全可以实现这个需求——只是需要我们基于它的LINQ to JSON API自己写递归遍历的逻辑来生成扁平键。下面是完整的实现步骤和代码:

核心实现思路

我们需要递归遍历JSON的每个节点,同时记录当前节点的路径(比如Data[0].UserInformation.City这种格式),最后将所有叶子节点的键值对整理到字典中。具体分三种情况处理:

  • JObject(JSON对象):遍历每个属性,拼接属性名到路径后递归处理属性值
  • JArray(JSON数组):遍历每个元素,用[索引]的格式拼接路径后递归处理元素
  • JValue(JSON值类型):将当前路径作为键,值转为字符串存入字典

完整代码实现

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

public static class JsonFlattener
{
    public static Dictionary<string, string> FlattenJson(JToken token, string currentPath = "")
    {
        var result = new Dictionary<string, string>();

        switch (token.Type)
        {
            case JTokenType.Object:
                foreach (JProperty property in token.Children<JProperty>())
                {
                    string newPath = string.IsNullOrEmpty(currentPath) 
                        ? property.Name 
                        : $"{currentPath}.{property.Name}";
                    result.AddRange(FlattenJson(property.Value, newPath));
                }
                break;

            case JTokenType.Array:
                int index = 0;
                foreach (JToken item in token.Children())
                {
                    string newPath = $"{currentPath}[{index}]";
                    result.AddRange(FlattenJson(item, newPath));
                    index++;
                }
                break;

            case JTokenType.Integer:
            case JTokenType.Float:
            case JTokenType.String:
            case JTokenType.Boolean:
            case JTokenType.Null:
                if (!string.IsNullOrEmpty(currentPath))
                {
                    result.Add(currentPath, token.ToString());
                }
                break;
        }

        return result;
    }

    // 扩展方法:方便合并两个字典
    private static void AddRange<TKey, TValue>(this Dictionary<TKey, TValue> target, Dictionary<TKey, TValue> source)
    {
        foreach (var pair in source)
        {
            target.Add(pair.Key, pair.Value);
        }
    }
}

测试你的JSON数据

注意你的原始JSON里有个小语法错误:"country:"应该是"country"(多了个冒号),修正后我们来测试:

using System;
using Newtonsoft.Json.Linq;

class Program
{
    static void Main()
    {
        string json = @"
        { 
            ""Name"" : ""Value1"", 
            ""Data"": [ 
                { 
                    ""UserName"": ""test"", 
                    ""email"": ""test@test.com"", 
                    ""UserInformation"": { 
                        ""City"": ""city"", 
                        ""country"": ""country"" 
                    } 
                }, 
                { 
                    ""UserName"": ""test1"", 
                    ""email"": ""test1@test.com"" 
                } 
            ] 
        }";

        JToken root = JToken.Parse(json);
        var flatDict = JsonFlattener.FlattenJson(root);

        // 输出结果验证
        foreach (var pair in flatDict)
        {
            Console.WriteLine($"""{pair.Key}"" : ""{pair.Value}""");
        }
    }
}

运行这段代码后,你会得到完全符合需求的扁平字典:

"Name" : "Value1"
"Data[0].UserName" : "test"
"Data[0].email" : "test@test.com"
"Data[0].UserInformation.City" : "city"
"Data[0].UserInformation.country" : "country"
"Data[1].UserName" : "test1"
"Data[1].email" : "test1@test.com"

关键细节说明

  • 扩展方法AddRange是为了方便递归时合并子字典的结果
  • 我们只处理了常见的JSON值类型(整数、浮点数、字符串、布尔、null),如果你的JSON有其他类型(比如日期),可以在JTokenType的case里补充处理
  • 路径拼接逻辑严格按照你要求的格式:数组用[索引],对象属性用.连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 21:33:00