为什么我需要在Json.Net中的foreach / Select()中调用.First()?

时间:2013-10-05 17:01:25

标签: c# json.net

我为这个可能很愚蠢的问题道歉,但是......

我有以下JSON (显然是简化的)

{
   "rgDescriptions":{
      "32895951_0":{
         "id":"32895951",
         "name":"Cat",
      },
      "61694787_0":{
         "id":"61694787",
         "name":"Dog",
      }
   }
}

作为我的问题的一个简单示例,这有效:

jsonObject["rgDescriptions"]["32895951_0"]["name"]

但这不是:

jsonObject["rgDescriptions"].First()["name"]
//InvalidOperationException:  Cannot access child value on Newtonsoft.Json.Linq.JProperty.

为了让它发挥作用,我需要将其更改为:

jsonObject["rgDescriptions"].First().First()["name"]

这对我没有意义,因为jsonObject["rgDescriptions"]中的第一个对象应该等同于["32895951_0"][]运算符和.First()都返回了一个JToken,所以我真的不明白为什么["rgDescriptions"].First()不起作用,或者它应该代表什么。

有人能向我解释发生了什么事吗?

1 个答案:

答案 0 :(得分:3)

首先,查看JToken是什么以及它可以包含什么可能会有所帮助。

  • JTokenJObjectJPropertyJArrayJValue的抽象基类。这些都代表了可以出现在JSON中的结构。
  • JObjectJProperty个对象的集合。它不能包含任何其他内容。
  • JProperty本质上是一个键值对。它有一个Name是一个字符串,Value是另一个JToken,不是JProperty

考虑到这一点,我们可以回答这个问题。

JObject["key"]使用给定密钥找到JProperty中的JObject,并返回JTokenValue部分JProperty部分JToken.First (如果未找到密钥,则为null)。

JToken返回给定JObject的第一个孩子。对于JProperty,第一个孩子是Value(不是JProperty的{​​{1}})。对于JProperty,第一个(也是唯一的)子项是Value的{​​{1}}。

他们为什么不一样?

好吧,如果JProperty方法返回JObject["key"]而不是其值,那么您将无法执行JProperty。相反,您必须使用更加繁琐的语法jsonObject["key1"]["key2"]["key3"]

相反,如果jsonObject["key1"].Value["key2"].Value["key3"]始终返回JToken.First的{​​{1}},则您永远无法使用它来发现Value JProperty }。 (如果您正在使用此方法,可能您不知道该属性的名称,而如果您使用其他方法,则确实知道它。)此外,导航属性,例如Name,{{ 1}}等不能正常工作,因为你在层次结构中处于错误的水平。