C#使用JsonFlatten处理含空格键JSON时Unflatten结构异常如何解决
解决JsonFlatten处理含空格JSON字段时Unflatten拆分错误问题
问题根因
你使用的JsonFlatten包默认的扁平化规则未对包含空格的键做特殊标记,Unflatten操作时会将空格识别为嵌套层级分隔符,因此将原本的单层键First Name错误拆分为两层嵌套结构。
解决方案
方案1:调整JsonFlatten调用参数(改动最小)
调用Flatten方法时传入参数,要求所有含空格的键用方括号包裹,Unflatten会自动识别方括号内的内容为完整键名,不会拆分:
string InputJson = File.ReadAllText(@"C:\Learnings\InputFile.json"); JObject jsonObject = JObject.Parse(InputJson); // 调整Flatten参数,含空格键用方括号包裹 var flattenedObj = jsonObject.Flatten( keySeparator: '.', wrapKeyPredicate: key => key.Contains(' '), wrapKeyFormat: "[{0}]" ); var unFlattenObj = flattenedObj.Unflatten(keySeparator: '.', keyWrapper: new SquareBracketKeyWrapper()); var JsonOutput = JsonConvert.SerializeObject(unFlattenObj, Formatting.Indented); Console.WriteLine(JsonOutput); File.WriteAllText(@"C:\Learnings\OutputFile.json", JsonOutput);
方案2:自定义实现扁平化/反扁平化逻辑(无需依赖第三方包)
如果第三方包参数不匹配,可以直接基于Newtonsoft.Json实现自定义的扁平化逻辑,完全可控,不会出现特殊字符拆分问题:
// 自定义扁平化方法 public static Dictionary<string, object> FlattenJObject(JObject jObj, string parentPath = "", char separator = '.') { var result = new Dictionary<string, object>(); foreach (var prop in jObj.Properties()) { var currentPath = string.IsNullOrEmpty(parentPath) ? prop.Name : $"{parentPath}{separator}{prop.Name}"; if (prop.Value is JObject childObj) { var childFlatten = FlattenJObject(childObj, currentPath, separator); foreach (var kv in childFlatten) { result.Add(kv.Key, kv.Value); } } else { result.Add(currentPath, prop.Value.ToObject<object>()); } } return result; } // 自定义反扁平化方法 public static JObject UnflattenDictionary(Dictionary<string, object> dict, char separator = '.') { var result = new JObject(); foreach (var kv in dict) { var parts = kv.Key.Split(separator); JToken current = result; for (int i = 0; i < parts.Length; i++) { var part = parts[i]; if (i == parts.Length - 1) { if (current is JObject currentObj) { currentObj[part] = JToken.FromObject(kv.Value); } } else { if (current[part] == null) { current[part] = new JObject(); } current = current[part]; } } } return result; }
调用时直接替换原有逻辑即可,可直接在扁平化后删除指定字段:
string InputJson = File.ReadAllText(@"C:\Learnings\InputFile.json"); JObject jsonObject = JObject.Parse(InputJson); var flattenedObj = FlattenJObject(jsonObject); // 此处可执行删除指定字段的逻辑,示例: // flattenedObj.Remove("Age"); // flattenedObj.Remove("Employement Details.SalaryReceived"); var unFlattenObj = UnflattenDictionary(flattenedObj); var JsonOutput = JsonConvert.SerializeObject(unFlattenObj, Formatting.Indented); Console.WriteLine(JsonOutput); File.WriteAllText(@"C:\Learnings\OutputFile.json", JsonOutput);
内容的提问来源于stack exchange,提问作者Madhanbm32
相关产品推荐
相关产品推荐

