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

Dub*_*her 43 .net c# serialization json 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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是:42 0

我宁愿抛出一个例外来默默地失败.没有办法检测序列化是否找不到参数?

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

Bri*_*ers 55

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

42
JsonSerializationException: Could not find member 'SomeOtherProperty' on object
of type 'MyJsonObjView'. Path 'SomeOtherProperty', line 3, position 33.
Run Code Online (Sandbox Code Playgroud)

  • 已经找到了解决方案。使用属性根据需要标记我的成员。 (2认同)

Jer*_*yal 13

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

[JsonProperty(Required = Required.Always)]
 public int MyJsonInt { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 这解决了一个互补的问题。如果您的 **模型** 具有您的 **JSON** 没有的属性,并且您希望该属性成为错误,请使用“[JsonProperty(Required = required.Always)]”。请参阅:[需要 JsonPropertyAttribute](https://www.newtonsoft.com/json/help/html/JsonPropertyRequired.htm)。如果您的 **JSON** 具有您的 **模型** 没有的属性,并且您希望该属性成为错误,请使用 `MissingMemberHandling = MissingMemberHandling.Error`。 (7认同)

Ada*_*lin 5

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

[DataMember(IsRequired = true)]
Run Code Online (Sandbox Code Playgroud)

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

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

[DataContract]
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案仅适用于您的班级上有“[DataContract]”且成员上没有“[JsonProperty]”的情况。(`JsonProperty` 覆盖 `DataMember`。)但是,您可以将 `[JsonProperty]` 属性上的 `Required` 参数设置为 `Required.Always` 以完成相同的操作。 (6认同)