我有一个实体,其中包括以下字段:CreatedBy
, CreatedAt
,ChangedAt
现在在视图中,我不希望用户填写这些字段。ModelState.IsValid
我的方法是在进行检查之前和将数据保存到数据库之前,在 HTTP POST 操作中填充它们。
但是,ModelState.IsValid
无论如何都会返回 false 。实现这一点的正确方法是什么?我应该ModelState.IsValid
从 POST 操作中获取验证 ( ) 吗?
我有一个实体,其中包括以下字段:CreatedBy
, CreatedAt
,ChangedAt
现在在视图中,我不希望用户填写这些字段。ModelState.IsValid
我的方法是在进行检查之前和将数据保存到数据库之前,在 HTTP POST 操作中填充它们。
但是,ModelState.IsValid
无论如何都会返回 false 。实现这一点的正确方法是什么?我应该ModelState.IsValid
从 POST 操作中获取验证 ( ) 吗?
一个问题,许多解决方案(在我看来,从最好到最坏)。
第一个解决方案
最好的方法是使用 ViewModel(仅包含必须由用户编辑和/或验证的字段的类)。
在这种情况下,CreatedBy、CreatedAt、ChangedAt 字段不会出现在您的 ViewModel 类中。
第二种解决方案
如果您不想要 ViewModel,您可以将“用户不可变”字段作为隐藏字段放在您的视图中
@Html.HiddenFor(m => m.CreatedAt)
当然,隐藏字段可以由用户更改,因此它总是对不需要的数据敞开大门......
第三个解决方案
在检查它是否有效之前清除ModelState
不需要的错误(如果您涉及许多领域,应该会变得非常无聊)。
if (ModelState.ContainsKey("CreatedAt")) {
ModelState["CreatedAt"].Errors.Clear();
}
//then test for ModelState.IsValid()
其他解决方案
用于模型绑定的白名单、黑名单,或者......我忘记的任何东西!
许多项目喜欢将View Model与Domain Model分开。这允许您创建一个 View-Model 类,专门为您希望在特定操作中呈现和/或接收的数据量身定制,同时保持域模型正确/一致。
在您的 View-Model 类中,您要么不将任何此类属性定义为创建日期(因为它不应该发布,而是在操作中确定)。或者,如果您使用同一个 View-Model 进行渲染和发布,并且想要渲染日期,则可以在 View-Model 上使日期为空(请参阅 Alexey 的回答),同时在域模型上保持强制。
DateTime 不可为空。如果您想在模型绑定期间将这些字段保持为空,如果它们没有值,请使用:
Nullable<DateTime>
或捷径:
DateTime?