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

.NET 6中如何将嵌套JSON扁平化并保留导航路径?

.NET 6 实现JSON嵌套对象扁平化(保留路径)

针对需求,这里提供两种基于Newtonsoft.Json(即JsonConvert/JObject)的高效实现方案:

方案一:递归遍历JObject实现扁平化

通过递归遍历JObject的所有节点,将嵌套路径用点号拼接后作为顶层键,值保留原数据。

步骤1:安装Newtonsoft.Json包

在项目中安装NuGet包:

Install-Package Newtonsoft.Json

步骤2:实现扁平化工具类

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

public static class JsonFlattener
{
    // 对外公开的扁平化方法
    public static JObject Flatten(JObject inputJson)
    {
        var flattenedResult = new JObject();
        TraverseToken(inputJson, string.Empty, flattenedResult);
        return flattenedResult;
    }

    // 递归遍历所有JToken节点
    private static void TraverseToken(JToken token, string currentPath, JObject result)
    {
        switch (token.Type)
        {
            // 遇到对象类型,继续遍历子属性
            case JTokenType.Object:
                foreach (JProperty property in token.Children<JProperty>())
                {
                    var newPath = string.IsNullOrEmpty(currentPath) 
                        ? property.Name 
                        : $"{currentPath}.{property.Name}";
                    TraverseToken(property.Value, newPath, result);
                }
                break;
            // 遇到数组可自行扩展逻辑,比如用`路径[索引]`格式
            case JTokenType.Array:
                // 示例:遍历数组元素并拼接索引路径
                // for (int i = 0; i < token.Count(); i++)
                // {
                //     var newPath = string.IsNullOrEmpty(currentPath) 
                //         ? $"[{i}]" 
                //         : $"{currentPath}[{i}]";
                //     TraverseToken(token[i], newPath, result);
                // }
                break;
            // 非对象/数组类型,直接存入结果
            default:
                if (!string.IsNullOrEmpty(currentPath))
                {
                    result[currentPath] = token;
                }
                break;
        }
    }
}

步骤3:使用示例

// 原始JSON字符串
string originalJson = @"{
   ""property1"":""value1"",
   ""property2"":""value2"",
   ""anotherObject"":{
      ""property1"":""anothervalue1"",
      ""property2"":""anothervalue2"",
      ""anotherOfAnother"":{
         ""property1"":""value1""
      }
   }
}";

// 解析为JObject并扁平化
JObject originalJObj = JObject.Parse(originalJson);
JObject flattenedJObj = JsonFlattener.Flatten(originalJObj);

// 输出格式化后的扁平化JSON
Console.WriteLine(flattenedJObj.ToString(Formatting.Indented));

方案二:自定义JsonConverter实现序列化时扁平化

如果需要在序列化对象时直接输出扁平化JSON,可以自定义JsonConverter,在序列化阶段自动处理路径拼接。

实现自定义转换器

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

public class FlattenedJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(object).IsAssignableFrom(objectType);
    }

    // 反扁平化逻辑可自行扩展,这里暂不实现
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("反扁平化逻辑需根据需求自行实现");
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // 将对象转为JObject后递归扁平化
        var jObject = JObject.FromObject(value, serializer);
        var flattened = new JObject();
        TraverseToken(jObject, string.Empty, flattened);
        flattened.WriteTo(writer);
    }

    // 复用之前的递归遍历方法
    private void TraverseToken(JToken token, string currentPath, JObject result)
    {
        switch (token.Type)
        {
            case JTokenType.Object:
                foreach (JProperty prop in token.Children<JProperty>())
                {
                    var newPath = string.IsNullOrEmpty(currentPath) 
                        ? prop.Name 
                        : $"{currentPath}.{prop.Name}";
                    TraverseToken(prop.Value, newPath, result);
                }
                break;
            case JTokenType.Array:
                // 按需扩展数组处理逻辑
                break;
            default:
                if (!string.IsNullOrEmpty(currentPath))
                {
                    result[currentPath] = token;
                }
                break;
        }
    }
}

使用示例

// 原始对象
var originalObject = new
{
    property1 = "value1",
    property2 = "value2",
    anotherObject = new
    {
        property1 = "anothervalue1",
        property2 = "anothervalue2",
        anotherOfAnother = new
        {
            property1 = "value1"
        }
    }
};

// 使用自定义转换器序列化
string flattenedJson = JsonConvert.SerializeObject(
    originalObject, 
    Formatting.Indented, 
    new FlattenedJsonConverter()
);

Console.WriteLine(flattenedJson);

效率说明

两种方案均基于Newtonsoft.Json的DOM模型(JObject)实现,递归遍历的方式在常规JSON结构下性能足够。如果处理超大JSON(GB级),可考虑流式处理方案,但大部分业务场景下递归DOM的方式已经满足需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:55:21