属性为 [必需] 且可为 null 意味着什么?

问题描述 投票:0回答:5

属性为

[Required]
且可为 null 意味着什么? (下面的例子)看来,如果是
[Required]
,就不可能是
null
(无值),如果能够是
null
,那也不可能是
[Required]

[Required]
public DateTime? OrderDate { get; set; }
c# asp.net-mvc data-annotations
5个回答
52
投票

将属性设为可为空并标记为

[Required]
属性的原因是为了防止低发布攻击。它还允许您在视图中显示初始空值而不是属性的默认值。这通常是通过视图模型中的值类型属性来完成的。

发布不足攻击是指恶意用户修改请求以省略请求中属性的值。如果属性为

DateTime
(不可为空),则
DefaultModelBinder
将初始化其默认值 (
01/01/0001
),并且不会生成
ModelState
错误。因此,该值可能会被保存,即使它不是您所期望的。

如果该属性为

DateTime?
(可空)且
[Required]
,那么如果恶意用户确实在请求中省略了该属性,则会生成
ModelState
错误,因为请求中需要一个值,而视图将被返回,因此无效数据将不会被保存。

另请参阅 Brad Wilson 的文章 ASP.NET MVC 中的输入验证与模型验证以及标题为 “发布不足”问题的部分。


9
投票

它可以为空,因此表单不会显示像

0001-01-01T00:00:00
这样没有意义的初始值。

需要强制用户输入一些内容。


6
投票

required
用于客户端验证,
nullable
用于数据库映射


6
投票

必需的是视图的数据注释。该视图将要求它在接受表单帖子之前具有一个值。

该值可以为空与数据库中允许的值有关。数据库中的值可能为 null,或者该值可能会保留为 null。

它们是不同的方面。


0
投票

在检查项目中的问题时,遇到了规则 csharpsquid:S6964:

在控制器操作中用作输入的值类型属性应该可以为空、必需或使用 JsonRequiredAttribute 进行注释,以避免发布不足。

为什么将可空类型与[必需]一起使用?

[Required] 属性旨在确保客户端在发出请求时显式提供值。然而,在某些情况下,它本身并不能有效地发挥作用,尤其是对于不可为空值类型。

原因如下:

默认值分配

当客户端省略不可为 null 的值类型属性(例如 int、decimal、bool)时,模型绑定器不能将其保留为未设置。相反,它分配类型的默认值:

整数 → 0 布尔→假 小数 → 0.0 这种自动分配可能会导致意外行为(称为发布不足),因为默认值可能不代表来自客户端的有效输入。

可空类型作为解决方案

通过将属性声明为可为空(例如,int?、bool?、decimal?),您可以创建一个值可以显式为空的状态。 当与 [Required] 属性结合使用时,模型绑定器强制客户端必须提供有效值或将其显式设置为 null。这可确保该属性永远不会无意中设置为其默认值。

我的想法

虽然这种方法解决了问题,但实现它需要在整个代码库中添加大量空检查,这可能会增加复杂性和维护开销。

因此,我选择在该项目的 SonarQube 中禁用此规则。

© www.soinside.com 2019 - 2024. All rights reserved.