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

时间:2014-01-09 20:43:59

标签: c# .net json serialization 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对象解析数据,然后使用键值查找检查参数,但我所使用的代码库使用上面的模式,如果可能,我希望保持一致。

5 个答案:

答案 0 :(得分:42)

Json.Net序列化程序设置为MissingMemberHandling,您可以将其设置为Error。 (默认值为Ignore。)这会导致序列化程序在遇到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.

答案 1 :(得分:10)

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

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

答案 2 :(得分:3)

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

[DataMember(IsRequired = true)]

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

正如Brian在下面建议的那样,你的班级也需要这个属性:

[DataContract]

答案 3 :(得分:0)

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

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

如果未初始化,则只有null,否则它将是有效值。这允许您设置可选设置并根据每个设置进行评估。

答案 4 :(得分:0)

@dbc在评论中指出:

  • 反序列化时:

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

  • 序列化时:

如果您的JSON具有Model所没有的属性,并且您想让它成为错误,请使用MissingMemberHandling = MissingMemberHandling.Error

当属性类型为可空时,也使用[DataMember(IsRequired = true)]进行反序列化时的错误为true。