c# - JContainer、JObject、JToken和Linq混淆

标签 c# json linq json.net

我无法理解何时使用 JContainerJObjectJToken。我从“标准”中了解到 JObjectJProperties 组成,并且 JToken 是所有 JToken 的基本抽象类 类型,但我不明白 JContainer.

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

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

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

此时,我将 JSON 字符串对象反序列化为 JObject (这可能是我的错误——也许我需要将 jsonWork 设为 JToken 还是 JContainer?):

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

在我的 JSON 数据(JSON 表示的字符串)中,我有三个对象——顶级对象看起来类似于:

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

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

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

// 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"];

然后我在 jsonObject1 中得到一个 JObject 类型。这是正确的方法吗?

JTokenJObject 对象似乎可以很好地与 LINQ 配合使用时,我不清楚何时/为什么会使用 JContainerJContainer的目的是什么?

最佳答案

在大多数情况下,您真的不需要担心 JContainer。它可以帮助组织和构建LINQ-to-JSON转换成良好分解的代码。

JToken层次结构如下所示:

JToken             - abstract base class     
   JContainer      - abstract base class of JTokens that can contain other JTokens
       JArray      - represents a JSON array (contains an ordered list of JTokens)
       JObject     - represents a JSON object (contains a collection of JProperties)
       JProperty   - represents a JSON property (a name/JToken pair inside a JObject)
   JValue          - represents a primitive JSON value (string, number, boolean, null)

所以你看,JObject JContainer , JToken .

这是基本的经验法则:

  • 如果您知道自己有一个对象(在 JSON 中用大括号 {} 表示),请使用 JObject
  • 如果您知道自己有一个数组或列表(用方括号 [] 表示),请使用 JArray
  • 如果您知道自己有一个原始值,请使用 JValue
  • 如果您不知道自己拥有哪种 token ,或者希望能够以一般方式处理上述任何一种,请使用 JToken .然后,您可以检查它的 Type 属性以确定它是什么类型的 token 并适本地转换它。

关于c# - JContainer、JObject、JToken和Linq混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38558844/

相关文章:

c# - 如何在 C# 中从 HTML 字符串操作 DOM?

c# - Java 的静态概念与 C# 的有何不同?

c# - 以 yyyy/MM/dd HH :mm:ss cause validation error in asp.net mvc 格式保存日期时间

java - @JsonUnwrapped 用于自定义序列化器

c# - 如何将 IEnumerable<object> 转换为 List<IFoo>,其中每个对象都是一个 IFoo?

c# - 如何在 C# 中使用 Microsoft.Azure.Management.Automation AutomationClient 启动 Azure runbook/webhook?

python - 将数据帧转换为 JSON,并使用 1 个公共(public)值列作为数组字段

json - 注册自定义 JSON 编码器

linq - Entity Framework 表之间的多重关系

c# - 根据特定成员值查找列表中的重复项目