【问题标题】:string behavior in json.net: why is a null JToken replaced with a non-null value?json.net 中的字符串行为:为什么将空 JToken 替换为非空值?
【发布时间】:2018-08-09 22:30:20
【问题描述】:

这使用 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

【问题讨论】:

标签: c# null json.net


【解决方案1】:

这是设计使然。

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

    internal JToken EnsureParentToken(JToken item, bool skipParentCheck)
    {
        if (item == null)
        {
            return JValue.CreateNull();
        }

还有JProperty.Value:

    public JToken Value
    {
        set
        {
            CheckReentrancy();

            JToken newValue = value ?? JValue.CreateNull();

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

{
   "field1": null
}

还有空对象:

{ }

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

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

如果您不需要区分缺失值和空值属性,您可以引入扩展方法来检查空值,例如 Checking for empty/null JToken in a JObjectIssue with JSON null handling in Newtonsoft.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多