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

C#无需提前知晓键名动态加载JSON文件全量嵌套内容的实现咨询

可行实现方案(基于Newtonsoft.Json)

你可以通过递归遍历JToken类型的所有节点实现无预设键名的JSON读写,完整实现逻辑如下:

核心实现步骤

  • 第一步:JSON解析后用递归遍历所有层级的节点,同时生成每个值节点的完整访问路径(嵌套节点用.分隔,数组成员带下标标记),避免提前硬编码键名
  • 第二步:动态生成TextBox时,将对应节点的完整路径存入控件的Tag属性,建立控件与JSON节点的映射关系
  • 第三步:用户修改内容后,通过路径定位到对应JSON节点直接更新值,最后重新序列化即可得到修改后的JSON

代码示例

1. 递归遍历JSON节点,生成键值对与路径映射

using Newtonsoft.Json.Linq;
// 存储所有值节点的【完整路径: 原始节点】映射
Dictionary<string, JToken> jsonNodeMap = new Dictionary<string, JToken>();
JToken rootJson;

// 递归遍历方法
void TraverseJson(JToken node, string parentPath = "")
{
    switch (node.Type)
    {
        // 处理对象类型,遍历所有属性
        case JTokenType.Object:
            foreach (JProperty prop in node.Children<JProperty>())
            {
                string currentPath = string.IsNullOrEmpty(parentPath) ? prop.Name : $"{parentPath}.{prop.Name}";
                TraverseJson(prop.Value, currentPath);
            }
            break;
        // 处理数组类型,遍历所有下标元素
        case JTokenType.Array:
            for (int i = 0; i < node.Count(); i++)
            {
                string currentPath = $"{parentPath}[{i}]";
                TraverseJson(node[i], currentPath);
            }
            break;
        // 处理值类型(字符串、数字、布尔等最终值)
        default:
            jsonNodeMap.Add(parentPath, node);
            // 直接生成TextBox添加到FlowLayoutPanel
            TextBox tb = new TextBox();
            tb.Name = $"txt_{parentPath}";
            tb.Tag = parentPath; // 存储路径用于后续更新定位
            tb.Text = node.ToString();
            tb.Width = 300;
            // 绑定文本变化事件实时同步,也可改为提交时统一遍历处理
            tb.TextChanged += Tb_TextChanged;
            flowLayoutPanel1.Controls.Add(tb);
            break;
    }
}

2. 加载JSON的初始化调用

string contents = File.ReadAllText("SomeJsonFile.txt");
rootJson = JToken.Parse(contents);
jsonNodeMap.Clear();
flowLayoutPanel1.Controls.Clear();
TraverseJson(rootJson);

3. 文本修改同步更新JSON节点

private void Tb_TextChanged(object sender, EventArgs e)
{
    TextBox tb = sender as TextBox;
    string path = tb.Tag as string;
    if (jsonNodeMap.TryGetValue(path, out JToken node))
    {
        // 自动转换值类型,也可根据原节点的JTokenType做更严格的格式校验
        JToken newValue = JToken.FromObject(tb.Text);
        if (node.Parent is JProperty prop)
        {
            prop.Value = newValue;
        }
        else if (node.Parent is JArray array)
        {
            int index = int.Parse(path.Substring(path.LastIndexOf('[') + 1).TrimEnd(']'));
            array[index] = newValue;
        }
    }
}

4. 导出修改后的JSON

string modifiedJson = rootJson.ToString(Newtonsoft.Json.Formatting.Indented);
File.WriteAllText("ModifiedJsonFile.txt", modifiedJson);

可选优化点

如果需要保证值类型和原始JSON一致,可以在递归记录节点时同时存储JTokenType,用户修改后先做类型校验(比如数字类型不允许输入非数字字符),避免修改后JSON格式不符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 12:27:04