我正在尝试使用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对象解析数据,然后使用键值查找检查参数,但我所使用的代码库使用上面的模式,如果可能,我希望保持一致。
答案 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。