C#解析JSON响应时排除null JValue筛选非空Pinpoint JToken节点
问题场景
现有如下JSON结构:
[ { "Id": 885758, "IssueId": 611932, "Pinpoint": { "Name": null, "Position": { "X": -32.452857971191406, "Y": -14.971426010131836, "Z": 9.111014366149902 }, "Element1": null, "Element2": null } }, { "Id": 885764, "IssueId": 611932, "Pinpoint": { "Name": null, "Position": { "X": -21.042057037353516, "Y": -21.742080688476562, "Z": 7.72857141494751 }, "Element1": null, "Element2": null } }, { "Id": 885765, "IssueId": 611932, "Pinpoint": null } ]
需求是获取所有Pinpoint节点值不为null的List<JToken>集合,期望返回结构如下:
[ { "Pinpoint": { "Name": null, "Position": { "X": -32.452857971191406, "Y": -14.971426010131836, "Z": 9.111014366149902 }, "Element1": null, "Element2": null } }, { "Pinpoint": { "Name": null, "Position": { "X": -21.042057037353516, "Y": -21.742080688476562, "Z": 7.72857141494751 }, "Element1": null, "Element2": null } } ]
未添加where条件的普通LINQ select查询返回结果参考:
错误写法原因
之前尝试的三种写法均报错,核心问题是LINQ执行顺序逻辑错误:
- 所有写法都先执行
Select(x => x["Pinpoint"]),执行后序列中的元素已经是原始数组中每个对象的Pinpoint属性值,不再是外层的原始对象 - 后续
Where中再调用x["Pinpoint"],相当于在Pinpoint节点本身下查找不存在的Pinpoint子属性:- 遇到
Pinpoint值为null的JValue节点时,访问子节点会抛出Cannot access child value on Newtonsoft.Json.Linq.JValue - 对null值调用
.HasValues、.Type属性时,会触发空引用异常
- 遇到
正确实现代码
按照需求返回带Pinpoint外层键的结果集,代码如下:
using Newtonsoft.Json.Linq; List<JToken> results = JArray.Parse(response.Content) // 第一步:在原始数组元素上过滤,排除Pinpoint为null的项 .Where(item => item["Pinpoint"] != null && item["Pinpoint"].Type != JTokenType.Null) // 第二步:投影为仅包含Pinpoint属性的JObject,匹配目标结构 .Select(item => new JObject( new JProperty("Pinpoint", item["Pinpoint"]) )) .ToList<JToken>();
如果不需要外层Pinpoint包装,直接返回非null的Pinpoint节点本身,可以用更简洁的写法:
List<JToken> results = JArray.Parse(response.Content) .Select(item => item["Pinpoint"]) .Where(pinpoint => pinpoint != null && pinpoint.Type != JTokenType.Null) .ToList();
内容的提问来源于stack exchange,提问作者uwponcel
相关产品推荐
相关产品推荐

