使用Linq查询JSON时报Cannot access child value on JProperty错误
报错原因与解决方案
错误原因
该报错是因为对非集合类型的JSON节点错误使用了遍历方法:
Where是针对JSON数组(对应Newtonsoft.Json中的JArray类型)的遍历方法,而Nvidia API返回的searchedProducts.featuredProduct字段是单个JSON对象(对应JObject类型),不是数组。- 对单个
JObject直接调用Where方法时,会枚举该对象下的所有JProperty(即JSON键值对的键属性),此时lambda表达式中的n为JProperty类型,无法通过索引访问子值,就会抛出该异常。 - 你之前处理
searchedProducts下的其他字段可以正常运行,是因为那些字段属于JSON数组类型,符合Where方法的使用前提。
修复方案
场景1:featuredProduct固定为单个对象
直接去掉遍历逻辑,单独判断取值即可,示例代码如下:
const string url = ""; const int refresh = 3000; string json = getGpuFromNvidia(url); var jsonParse = JObject.Parse(json); List<CarteGraphique> result = new List<CarteGraphique>(); var featuredProduct = jsonParse["searchedProducts"]?["featuredProduct"] as JObject; if (featuredProduct != null && featuredProduct["isFounderEdition"]?.Value<bool>() == true) { result.Add(new CarteGraphique { displayName = (string)featuredProduct["displayName"], prdStatus = (string)featuredProduct["prdStatus"], directPurchaseLink = (string)featuredProduct["retailers"]?[0]?["directPurchaseLink"] }); }
场景2:featuredProduct可能为数组/单个对象
增加类型兼容判断,兼容两种返回结构:
const string url = ""; const int refresh = 3000; string json = getGpuFromNvidia(url); var jsonParse = JObject.Parse(json); List<CarteGraphique> result = new List<CarteGraphique>(); var featuredProductNode = jsonParse["searchedProducts"]?["featuredProduct"]; // 判断是否为数组 if (featuredProductNode is JArray productArray) { result = productArray .Where(n => n["isFounderEdition"]?.Value<bool>() == true) .Select(p => new CarteGraphique { displayName = (string)p["displayName"], prdStatus = (string)p["prdStatus"], directPurchaseLink = (string)p["retailers"]?[0]?["directPurchaseLink"] }) .ToList(); } // 判断是否为单个对象 else if (featuredProductNode is JObject singleProduct) { if (singleProduct["isFounderEdition"]?.Value<bool>() == true) { result.Add(new CarteGraphique { displayName = (string)singleProduct["displayName"], prdStatus = (string)singleProduct["prdStatus"], directPurchaseLink = (string)singleProduct["retailers"]?[0]?["directPurchaseLink"] }); } }
注:代码中加入了
?空传播符做空值校验,避免字段缺失、数组为空等异常场景下的报错。
内容的提问来源于stack exchange,提问作者Castiel
相关产品推荐
相关产品推荐

