json.net 中的字符串行为:为什么将空 JToken 替换为非空值?

use*_*654 3 c# null json.net

这使用 json.net (C#)。不知道为什么 JToken 不为空。

var obj = new JObject();
obj["field1"] = null;
var token = obj["field1"];

Console.WriteLine(token == null); // false 
Console.WriteLine(token.ToString() == ""); // true

Console.WriteLine(token.Type == JTokenType.Null); // true
Run Code Online (Sandbox Code Playgroud)

dbc*_*dbc 8

这是设计使然。

Json.NET 从不允许实际的空JToken值出现在JToken层次结构中,无论是作为JArray成员还是作为JProperty值。相反,如果应用程序代码尝试设置或添加null令牌,它会被替换为等于的非空值JValue。这种替换发生在,例如:JValue.TypeJTokenType.NullJContainer.EnsureParentToken(JToken item, bool skipParentCheck)

    internal JToken EnsureParentToken(JToken item, bool skipParentCheck)
    {
        if (item == null)
        {
            return JValue.CreateNull();
        }
Run Code Online (Sandbox Code Playgroud)

以及JProperty.Value

    public JToken Value
    {
        set
        {
            CheckReentrancy();

            JToken newValue = value ?? JValue.CreateNull();
Run Code Online (Sandbox Code Playgroud)

我相信 Newtonsoft 这样做是为了捕捉以下两个 JSON 对象之间的差异:

{
   "field1": null
}
Run Code Online (Sandbox Code Playgroud)

和空对象:

{ }
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,该属性"field1"带有一个nullJSON 值。在第二种情况下,该属性"field1"不存在。Linq-to-JSON 表示第一种情况为 null 类型JValue而不是JProperty.Value实际为 null。它可能会这样做,因为如果不这样做,在两种情况下object["field1"]都会返回null,使它们更难区分。(与 不同Dictionary<TKey, TValue>,在尝试访问不存在的属性的值时JObject不会抛出 a KeyNotFoundException。相反,为缺少的键的值JObject.Item[String]返回 null JValue。)

您的代码 ,obj["field1"] = null;创建了第一种形式的 JSON 对象,如果您检查 的值,您就可以看到该对象obj.ToString()。因此obj["field1"]返回非空

如果您不需要区分缺失值和空值属性,您可以引入一种扩展方法来检查空值,例如检查 JObject 中的空/空 JTokenJSON 空处理问题中的方法之一在牛顿软件