在ASP.NET核心模型中使用Required和JsonRequired与JSON主体绑定

Far*_*zad 5 c# model-binding json.net asp.net-core-2.0

我正在使用ASP.NET Core 2.0,我有一个请求对象注释如下:

public class MyRequest
{
    [Required]
    public Guid Id { get; set; }

    [Required]
    public DateTime EndDateTimeUtc { get; set; }

    [Required]
    public DateTime StartDateTimeUtc { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在我的控制器中:

public async Task<IActionResult> HandleRequest([FromBody] MyRequest request)
{ /* ... */ }
Run Code Online (Sandbox Code Playgroud)

我注意到一个问题与模型绑定:当我发送包含该头的请求Content-Type设置为application/json和一个空的身体,我想到,request在我的控制器是nullModelState.IsValidfalse.

但是当我有这样的身体时:

{
  "hello": "a-string-value!"
}
Run Code Online (Sandbox Code Playgroud)

request不是null,它有一切的默认值,而且ModelState.IsValidtrue

这当然发生在我缺少所有Required属性的时候,并且唯一存在的名称与那里的属性不匹配(即使是这个单个参数的类型string,也与我的模型上的任何类型都不匹配).

所以在某种程度上,Required如果我的请求中没有任何内容,那些属性似乎正在起作用,但如果我的请求不为空,它们就不会做任何事情!

当我准备这个问题时,我注意到还有一个JsonRequired属性,它似乎照顾到存在的属性.

那么,Required和之间的区别是JsonRequired什么?

Cod*_*ler 11

为了正确处理Required属性,您应该使属性可以为空:

public class MyRequest
{
    [Required]
    public Guid? Id { get; set; }

    [Required]
    public DateTime? EndDateTimeUtc { get; set; }

    [Required]
    public DateTime? StartDateTimeUtc { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你缺少发送请求Id,EndDateTimeUtc或者StartDateTimeUtc,相应的字段将被设置为null,ModelState.IsValid将被设置为falseModelState将包含错误的结果说明,如The EndDateTimeUtc field is required.

JsonRequired属性特定于JSON.Net.它在反序列化期间播放,而在模型验证期间,在反序列化模型之后播放Required属性(作为System.ComponentModel.DataAnnotations命名空间的其他属性).如果JsonRequired违反了属性,则根本不会反序列化模型,并将相应的操作参数设置为null.

您更喜欢Required属性的主要原因JsonRequired是它JsonRequired不适用于其他内容类型(如XML).Required反之亦然,因为它是在反序列化模型后应用的.