一尘不染

JContainer,JObject,JToken和Linq混淆

json

我无法理解时使用JContainerJObjectJToken。我从该“标准”的理解JObject是由JPropertiesJToken是所有的基础抽象类JToken的类型,但我不明白JContainer

我正在使用C#,而我刚购买了LinqPad Pro 5。

我在文件中有一个JSON数据源,因此我正在使用以下语句成功反序列化该文件的内容:

string json;
using (StreamReader reader = new StreamReader(@"myjsonfile.json"))
{
    json = reader.ReadToEnd();
}

那时,我将JSON字符串对象反序列化为a JObject(这可能是我的错误-
也许我需要jsonWork输入JTokenor或JContainer?):

JObject jsonWork = (JObject)JsonConvert.DeserializeObject(json);

在我的JSON数据(由JSON表示的字符串)中,我有三个对象-顶级对象与此类似:

{
  "Object1" : { ... },
  "Object2" : { ... },
  "Object3" : { ... }
}

每个对象都由各种标记(数组,字符串,其他对象等)组成,因此它是动态JSON。(我使用省略号作为占位符,而不是用大量JSON数据弄混了这个问题。)

我要处理"Object1""Object2""Object3"单独使用LINQ,但是。所以,理想情况下,我想要这样的东西:

// these lines DO NOT work    
var jsonObject1 = jsonWork.Children()["Object1"]
var jsonObject2 = jsonWork.Children()["Object2"]
var jsonObject3 = jsonWork.Children()["Object3"]

但是以上几行失败了。

我用var上面的,因为我不知道我应该使用什么样的对象类型:JContainerJObjectJToken!就是这样,您知道我想做什么,一旦jsonObject#正确分配了上述变量,我想使用LINQ来查询它们包含的JSON。这是一个非常简单的示例:

var query = from p in jsonObject1
   where p.Name == "Name1"
   select p

当然,我的LINQ最终将在jsonObject变量中过滤JSON数组,对象,字符串等。我想一旦开始,我可以使用LinqPad来帮助我使用LINQ过滤JSON。

我发现如果我使用:

// this line WORKS 
var jsonObject1 = ((JObject)jsonWork).["Object1"];

然后我JObject输入jsonObject1。这是正确的方法吗?

目前还不清楚我的时候/为什么人会使用JContainer的时候似乎JTokenJObject反对使用LINQ工作得很好。目的是JContainer什么?


阅读 397

收藏
2020-07-27

共1个答案

一尘不染

JContainer是具有子项的JSON元素的基类。JObjectJArrayJPropertyJConstructor从它的所有继承。

例如,以下代码:

(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")

会抛出一个InvalidCastException,但是如果将其强制转换为JContainer,那就很好了。

关于您的原始问题,如果知道您在顶层有JSON对象,则可以使用:

var jsonWork = JObject.Parse(json);
var jsonObject1 = jsonWork["Object1"];
2020-07-27