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
相关产品推荐
相关产品推荐

