[英]Using Required and JsonRequired in ASP.NET Core Model Binding with JSON body
我正在使用 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; }
}
在我的控制器中:
public async Task<IActionResult> HandleRequest([FromBody] MyRequest request)
{ /* ... */ }
我注意到模型绑定的一个问题:当我发送一个包含设置为application/json
的标头Content-Type
和一个空主体的request
,正如我所料,我的控制器中的request
为null
并且ModelState.IsValid
为false
。
但是当我有这样的身体时:
{
"hello": "a-string-value!"
}
我的request
不是null
,它对所有内容都有默认值,并且ModelState.IsValid
为true
这当然会发生,因为我缺少所有Required
属性,并且唯一存在的名称与那里的属性不匹配(即使这个单个参数的类型是string
,它与我的模型上的任何类型都不匹配) .
所以在某种程度上,如果我的请求中没有任何内容,那些Required
属性似乎正在工作,但如果我的请求不为空,它们就不会做任何事情!
当我准备这个问题时,我注意到还有一个JsonRequired
属性,它似乎处理存在的属性。
那么, Required
和JsonRequired
之间有什么区别呢?
为了使Required
属性正确工作,您应该使属性可以为空:
public class MyRequest
{
[Required]
public Guid? Id { get; set; }
[Required]
public DateTime? EndDateTimeUtc { get; set; }
[Required]
public DateTime? StartDateTimeUtc { get; set; }
}
现在,如果您发送缺少Id
、 EndDateTimeUtc
或StartDateTimeUtc
请求,则相应字段将设置为null
, ModelState.IsValid
将设置为false
并且ModelState
将包含错误描述,例如The EndDateTimeUtc field is required.
JsonRequired
属性特定于 JSON.Net。 它在反序列化期间播放,而Required
属性(作为System.ComponentModel.DataAnnotations
命名空间中的其他属性)在模型反序列化之后,在模型验证期间播放。 如果违反了JsonRequired
属性,则模型根本不会反序列化,并且相应的操作参数将设置为null
。
您应该更喜欢Required
属性而不是JsonRequired
是JsonRequired
不适用于其他内容类型(如 XML)。 反过来, Required
是通用的,因为它是在模型反序列化后应用的。
当您使用[FromBody]
作为绑定源时,模型属性将获得默认值,而[BindRequired]
将被忽略。 “参数验证问题”上有一个相关问题。
在这种情况下,最好使用[JsonRequired]
而不是[BindRequired]
来强制执行绑定属性。
请注意, [JsonRequired]
影响序列化和反序列化。
是的,困难在于,如果您选择必需,则 Web 请求客户端的语义更改不正确 - 即您说您可以传入一个 null,当您确实需要一个正确的值时。
使用 JsonRequired 对此进行排序,但这是由 NewtonSoft 提供的,因此当您升级到 .Net Core 3 时停止工作。这是因为 .Net Core 3 使用其自己的 Json 解析器而不是 NewtonSoft。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.