ModelState.IsValid为false,因为CreatedBy字段为null

时间:2013-09-27 11:03:16

标签: asp.net-mvc asp.net-mvc-4

我有一个实体,其中包括以下字段:CreatedByCreatedAtChangedAt

现在在视图中,我不希望用户填写这些字段。 我的方法是在进行ModelState.IsValid检查之前和将数据保存到数据库之前填写HTTP POST操作。

然而,无论如何,ModelState.IsValid都会不断返回假。实现这个的正确方法是什么?我应该从POST操作中获取验证(ModelState.IsValid)吗?

3 个答案:

答案 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?