.NET 6中System.Text.Json添加JsonNode遇‘节点已有父级’异常求助
解决System.Text.Json中JsonNode添加到新数组时的"节点已有父节点"异常
问题核心在于System.Text.Json的JsonNode实例是有父节点关联的,每个节点只能属于一个父容器(比如JsonArray或JsonObject)。你从接口响应中提取的responseData数组里的每个元素,其Parent属性已经指向responseData,直接将这些元素添加到allData时,就会触发"节点已有父节点"的异常。
下面是几种可行的解决方法:
方法1:克隆节点后添加
使用JsonNode.DeepClone()方法复制每个节点,克隆后的节点没有父节点关联,可以安全添加到新数组中:
JsonArray allData = new(); ... var httpResponse = await _httpClient.GetAsync("my url"); var responseObject = await httpResponse.Content.ReadFromJsonAsync<JsonNode>(); var responseData = responseObject["myKey"].AsArray(); // 无需重复Parse,直接转数组即可 foreach(var obj in responseData) { // 执行你的操作 // 克隆节点 var clonedObj = obj.DeepClone(); allData.Add(clonedObj); }
也可以用LINQ简化添加逻辑:
allData.AddRange(responseData.Select(node => node.DeepClone()));
方法2:使用JsonElement中转(无父节点限制)
JsonElement是无状态的、只读的JSON表示,没有父节点关联。可以先将响应反序列化为JsonElement,再转成JsonNode实例,这样每个新实例都属于allData:
JsonArray allData = new(); ... var httpResponse = await _httpClient.GetAsync("my url"); var responseElement = await httpResponse.Content.ReadFromJsonAsync<JsonElement>(); if (responseElement.TryGetProperty("myKey", out var responseDataElement) && responseDataElement.ValueKind == JsonValueKind.Array) { foreach (var element in responseDataElement.EnumerateArray()) { // 将JsonElement转成新的JsonNode实例 var obj = JsonNode.Parse(element.GetRawText()); // 执行你的操作 allData.Add(obj); } }
方法3:反序列化为强类型集合(如果适用)
如果你的响应数据结构固定,可以直接反序列化为强类型List,操作后再转成JsonArray:
// 先定义对应的数据类 public class ResponseItem { /* 对应responseData中元素的属性 */ } JsonArray allData = new(); ... var httpResponse = await _httpClient.GetAsync("my url"); var response = await httpResponse.Content.ReadFromJsonAsync<Dictionary<string, List<ResponseItem>>>(); var responseData = response["myKey"]; foreach(var item in responseData) { // 执行你的操作 // 转成JsonNode添加到数组 allData.Add(JsonSerializer.SerializeToNode(item)); }
内容的提问来源于stack exchange,提问作者TheMethod
相关产品推荐
相关产品推荐

