反序列化 JSON 仅当它为值类型 属性 指定值时
Deserialize JSON only if it specifies a value for a value type property
如果我有一个包含值类型属性的 DTO class,我如何才能惯用地使用 Newtonsoft 将 JSON 反序列化为我的 DTO class,同时确保 JSON定义值类型,可能包含该类型的 default
值?到目前为止,我看到的方法依赖于检查值是否为 default
值,但是,当 default
值也是 属性 的有效值时,这不是一个合适的解决方案.
例子
public class MyDto
{
public bool MyProp { get; set; }
}
JSON
Can deserialize to MyDto
{"MyProp": true}
true
{"MyProp": false}
true
{}
false
当前解
目前我使用 System.ComponentModel.DataAnnotations.RequiredAttribute
并将类型声明为可为空,但这仅在模型绑定期间有效(而不是任何反序列化),并导致在引用 [= 时过度使用 !
38=].
public class MyDto
{
[Required]
public bool? MyProp { get; set; }
}
我相信你要找的是 JsonPropertyAttribute Required 属性:
public class MyDto
{
[JsonProperty(Required = Required.Always)]
public bool MyProp { get; set; }
}
当被反序列化的 JSON 不包含指定的 属性 (MyProp
) 时,这会导致异常。例如,以下内容:
string json = "{\"MyProp\": true}";
MyDto myDto = JsonConvert.DeserializeObject<MyDto>(json);
Console.WriteLine(myDto.MyProp);
json = "{\"MyProp\": false}";
myDto = JsonConvert.DeserializeObject<MyDto>(json);
Console.WriteLine(myDto.MyProp);
json = "{}";
myDto = JsonConvert.DeserializeObject<MyDto>(json);
Console.WriteLine(myDto.MyProp);
给出结果:
True
False
Run-time exception (line 17): Required property 'MyProp' not found in JSON. Path '', line 1, position 2.
您可以使用 JSON 架构 (Newtonsoft.Json.Schema) 验证 JSON,如下所示:
public class MyDto
{
[JsonProperty(Required = Required.Always)]
public bool MyProp { get; set; }
}
var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(MyDto));
var dto = JObject.Parse(@"{ 'MyProp': true }");
bool isValid = dto.IsValid(schema);
Console.WriteLine(isValid); // True
dto = JObject.Parse(@"{}");
isValid = dto.IsValid(schema);
Console.WriteLine(isValid); // False
如果我有一个包含值类型属性的 DTO class,我如何才能惯用地使用 Newtonsoft 将 JSON 反序列化为我的 DTO class,同时确保 JSON定义值类型,可能包含该类型的 default
值?到目前为止,我看到的方法依赖于检查值是否为 default
值,但是,当 default
值也是 属性 的有效值时,这不是一个合适的解决方案.
例子
public class MyDto
{
public bool MyProp { get; set; }
}
JSON | Can deserialize to MyDto |
---|---|
{"MyProp": true} |
true |
{"MyProp": false} |
true |
{} |
false |
当前解
目前我使用 System.ComponentModel.DataAnnotations.RequiredAttribute
并将类型声明为可为空,但这仅在模型绑定期间有效(而不是任何反序列化),并导致在引用 [= 时过度使用 !
38=].
public class MyDto
{
[Required]
public bool? MyProp { get; set; }
}
我相信你要找的是 JsonPropertyAttribute Required 属性:
public class MyDto
{
[JsonProperty(Required = Required.Always)]
public bool MyProp { get; set; }
}
当被反序列化的 JSON 不包含指定的 属性 (MyProp
) 时,这会导致异常。例如,以下内容:
string json = "{\"MyProp\": true}";
MyDto myDto = JsonConvert.DeserializeObject<MyDto>(json);
Console.WriteLine(myDto.MyProp);
json = "{\"MyProp\": false}";
myDto = JsonConvert.DeserializeObject<MyDto>(json);
Console.WriteLine(myDto.MyProp);
json = "{}";
myDto = JsonConvert.DeserializeObject<MyDto>(json);
Console.WriteLine(myDto.MyProp);
给出结果:
True
False
Run-time exception (line 17): Required property 'MyProp' not found in JSON. Path '', line 1, position 2.
您可以使用 JSON 架构 (Newtonsoft.Json.Schema) 验证 JSON,如下所示:
public class MyDto
{
[JsonProperty(Required = Required.Always)]
public bool MyProp { get; set; }
}
var generator = new JSchemaGenerator();
var schema = generator.Generate(typeof(MyDto));
var dto = JObject.Parse(@"{ 'MyProp': true }");
bool isValid = dto.IsValid(schema);
Console.WriteLine(isValid); // True
dto = JObject.Parse(@"{}");
isValid = dto.IsValid(schema);
Console.WriteLine(isValid); // False