简体   繁体   English

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

[英]Deserialize JSON only if it specifies a value for a value type property

If I have a DTO class containing value type properties, how can I idiomatically use Newtonsoft to deserialize JSON to my DTO class while ensuring that the JSON defines the value type, possibly containing the default value for the type? If I have a DTO class containing value type properties, how can I idiomatically use Newtonsoft to deserialize JSON to my DTO class while ensuring that the JSON defines the value type, possibly containing the default value for the type? So far the methods I have seen rely on checking if the value is the default value, however, this is not a suitable solution when the default value is also a valid value for the property.到目前为止,我所看到的方法依赖于检查该值是否为default值,但是,当default值也是属性的有效值时,这不是一个合适的解决方案。

Example例子

public class MyDto
{
    public bool MyProp { get; set; }
}
JSON JSON Can deserialize to MyDto可以反序列MyDto
{"MyProp": true} true真的
{"MyProp": false} true真的
{} false错误的

Current solution当前解决方案

Currently I use System.ComponentModel.DataAnnotations.RequiredAttribute and declare the type as nullable, but this only works during model binding (instead of any deserialization), and leads to excessive use of !目前我使用System.ComponentModel.DataAnnotations.RequiredAttribute并将类型声明为可为空,但这仅在 model 绑定期间有效(而不是任何反序列化),并导致过度使用! when referencing the property.引用该属性时。

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

I believe what you're looking for is the JsonPropertyAttribute Required property:我相信您正在寻找的是JsonPropertyAttribute 必需的属性:

public class MyDto
{
    [JsonProperty(Required = Required.Always)]
    public bool MyProp { get; set; }
}

This results in an exception when the JSON being deserialized does not contain the specified property ( MyProp ).当反序列化的 JSON 不包含指定的属性 ( MyProp ) 时,这会导致异常。 For example, the following:例如,以下内容:

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

Gives the result:给出结果:

True
False
Run-time exception (line 17): Required property 'MyProp' not found in JSON. Path '', line 1, position 2.

You can validate the JSON using JSON Schema ( Newtonsoft.Json.Schema ) like this:您可以使用 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM