如何用System.Text.Json的JsonNode递归遍历层级(等效JToken.DescendantsAndSelf())
使用System.Text.Json的JsonNode递归移除JSON中所有指定属性
针对无固定Schema的JSON文档,要递归遍历并移除所有位置的"password"属性,由于JsonNode没有类似Json.NET中JToken.DescendantsAndSelf()的内置方法,我们可以自行实现递归遍历逻辑,具体方案如下:
实现递归遍历与属性移除方法
编写一个扩展方法,递归处理所有JsonObject和JsonArray类型的节点,移除目标属性并遍历子节点:
using System.Text.Json.Nodes; public static class JsonNodeExtensions { public static void RemoveAllPropertiesByName(this JsonNode node, string propertyName) { if (node is JsonObject jsonObj) { // 移除当前对象的目标属性 jsonObj.Remove(propertyName); // 递归处理每个子属性(ToList避免遍历中修改集合引发异常) foreach (var childNode in jsonObj.Values.ToList()) { childNode.RemoveAllPropertiesByName(propertyName); } } else if (node is JsonArray jsonArray) { // 递归处理数组中的每个元素 foreach (var item in jsonArray.ToList()) { item?.RemoveAllPropertiesByName(propertyName); } } // JsonValue类型无需处理 } }
示例用法
以下是完整的使用示例,解析JSON并移除所有"password"属性:
// 待处理的JSON字符串 string rawJson = @" { ""user"": { ""name"": ""Alice"", ""password"": ""123456"", ""profile"": { ""password"": ""abc789"", ""email"": ""alice@example.com"" } }, ""accounts"": [ { ""id"": 1, ""password"": ""pass1"" }, { ""id"": 2, ""password"": ""pass2"" } ] }"; // 解析为JsonNode JsonNode rootNode = JsonNode.Parse(rawJson)!; // 移除所有"password"属性 rootNode.RemoveAllPropertiesByName("password"); // 输出格式化后的结果 Console.WriteLine(rootNode.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
关键说明
- 遍历集合时调用
ToList():避免在遍历过程中修改集合(如移除属性)导致的枚举异常 - 递归覆盖所有层级:无论是嵌套的对象还是数组中的对象,都会被遍历处理
- 类型分支处理:针对
JsonObject处理属性移除,JsonArray处理元素遍历,JsonValue直接跳过
内容的提问来源于stack exchange,提问作者dbc
相关产品推荐
相关产品推荐

