仅当 JSON 为值类型属性指定一个值时才反序列化它

问题描述

如果我有一个包含值类型属性的 DTO 类,我如何惯用地使用 Newtonsoft 将 JSON 反序列化为我的 DTO 类,同时确保 JSON 定义值类型,可能包含该类型的 default 值?到目前为止,我看到的方法依赖于检查值是否为 default 值,但是,当 default 值也是属性的有效值时,这不是合适的解决方案。

示例

public class MyDto
{
    public bool MyProp { get; set; }
}
JSON 可以反序列化为 MyDto
{"MyProp": true} 真实
{"MyProp": false} 真实
{}

目前的解决方

目前我使用 System.ComponentModel.DataAnnotations.requiredAttribute 并将类型声明为可为空,但这仅在模型绑定期间有效(而不是任何反序列化),并导致在引用属性时过度使用 !。>

public class MyDto
{
    [required]
    public bool? MyProp { get; set; }
}

解决方法

我相信您正在寻找的是 JsonPropertyAttribute Required 属性:

for i in range(9):
    for j in range(1,i+1):
        print((i*j),end=" ")
    print("\n")

当被反序列化的 JSON 不包含指定的属性 (public class MyDto { [JsonProperty(Required = Required.Always)] public bool MyProp { get; set; } } ) 时,这会导致异常。例如,以下内容:

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);
,

您可以像这样使用 JSON Schema (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