我有一个实体,其中包括以下字段:CreatedBy
,CreatedAt
,ChangedAt
现在在视图中,我不希望用户填写这些字段。
我的方法是在进行ModelState.IsValid
检查之前和将数据保存到数据库之前填写HTTP POST操作。
然而,无论如何,ModelState.IsValid
都会不断返回假。实现这个的正确方法是什么?我应该从POST操作中获取验证(ModelState.IsValid
)吗?
答案 0 :(得分:3)
一个问题,很多解决方案(在我看来,从最好到最差)。
第一个解决方案
最好的方法是使用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()
其他解决方案
WhiteList,BlackList for model binding,或者......我忘了的任何东西!
答案 1 :(得分:2)
许多项目都喜欢将 View Model 与 Domain Model 分开。这允许您创建一个View-Model类,专门为您希望在特定操作中呈现和/或接收的数据量身定制,同时保持域模型的正确/一致。
在View-Model类中,您不会将任何此类属性定义为创建日期(因为它不应该发布但在操作中确定)。或者,如果您使用同一个View-Model进行和发布,并且想要渲染日期,则可以在View模型上保留日期(参见Alexey的答案),同时保留日期域模型必须使用。
答案 2 :(得分:1)
DateTime不可为空。如果要在模型绑定期间将这些字段保留为null,如果没有值,则使用:
Nullable<DateTime>
或捷径:
DateTime?