You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 05:18:21