繁体   English   中英

使用 Json.NET 中的 JsonConvert 类检测反序列化对象是否缺少字段

[英]Detect if deserialized object is missing a field with the JsonConvert class in Json.NET

我正在尝试使用 Json.NET 反序列化一些 JSON 对象。 然而,我发现当我反序列化一个没有我正在寻找的属性的对象时,不会抛出任何错误,但是当我访问它们时会为这些属性返回一个默认值。 当我反序列化错误类型的对象时,我能够检测到这一点很重要。 示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Json_Fail_Test
{
    class Program
    {
        [JsonObject(MemberSerialization.OptOut)]
        private class MyJsonObjView
        {
            [JsonProperty("MyJsonInt")]
            public int MyJsonInt { get; set; }
        }

        const string correctData = @"
        {
            'MyJsonInt': 42
        }";

        const string wrongData = @"
        {
            'SomeOtherProperty': 'fbe8c20b'
        }";

        static void Main(string[] args)
        {
            var goodObj = JsonConvert.DeserializeObject<MyJsonObjView>(correctData);
            System.Console.Out.WriteLine(goodObj.MyJsonInt.ToString());

            var badObj = JsonConvert.DeserializeObject<MyJsonObjView>(wrongData);
            System.Console.Out.WriteLine(badObj.MyJsonInt.ToString());
        }
    }
}

这个程序的输出是:42 0

我宁愿抛出异常而不是静默失败。 除此之外,有没有办法检测序列化是否未能找到参数?

我知道我可以使用 Json 对象解析数据,然后使用键值查找检查参数,但我所在的代码库使用上面的模式,如果可能的话,我希望保持一致。

Json.Net 序列化程序有一个MissingMemberHandling设置,您可以将其设置为Error (默认为Ignore 。)这将导致序列化JsonSerializationException在反序列化期间在遇到目标类中没有对应属性的 JSON 属性时抛出JsonSerializationException

static void Main(string[] args)
{
    try
    {
        JsonSerializerSettings settings = new JsonSerializerSettings();
        settings.MissingMemberHandling = MissingMemberHandling.Error;

        var goodObj = JsonConvert.DeserializeObject<MyJsonObjView>(correctData, settings);
        System.Console.Out.WriteLine(goodObj.MyJsonInt.ToString());

        var badObj = JsonConvert.DeserializeObject<MyJsonObjView>(wrongData, settings);
        System.Console.Out.WriteLine(badObj.MyJsonInt.ToString());
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
    }
}

结果:

42
JsonSerializationException: Could not find member 'SomeOtherProperty' on object
of type 'MyJsonObjView'. Path 'SomeOtherProperty', line 3, position 33.

请参阅: MissingMemberHandling 设置

只需将[JsonProperty(Required = Required.Always)]到所需的属性中,如果反序列化时该属性不存在,它将抛出异常。

[JsonProperty(Required = Required.Always)]
 public int MyJsonInt { get; set; }

将以下属性放在必需的属性上:

[DataMember(IsRequired = true)]

如果该成员不存在,它将抛出 Newtonsoft.Json.JsonSerializationException。

正如布莱恩在下面建议的那样,您还需要在您的班级中使用此属性:

[DataContract]

只需在您的定义类中用问号“?”定义您的成员。 int?

private class MyJsonObjView
{
    [JsonProperty("MyJsonInt")]
    public int? MyJsonInt { get; set; }
}

当它未初始化时,它将只是null ,否则它将是一个有效值。 这使您可以选择设置并在每个设置的基础上评估它们。

正如@dbc 在评论中所说:

  • 在反序列化:

如果您的模型具有您的 JSON 没有的属性,并且您希望它成为错误,请使用[JsonProperty(Required = Required.Always)]

  • 序列化时:

如果您的 JSON 具有您的模型没有的属性,并且您希望它是一个错误,请使用MissingMemberHandling = MissingMemberHandling.Error

当 proeprty 类型为nullable时,还使用[DataMember(IsRequired = true)]进行反序列化错误为 true 。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM