我刚刚遇到了与SQL Server作为数据存储区的ASP.NET MVC应用程序一起使用的Entity框架实体的意外行为。对于标记为非null的列允许我没有设置数据注释实体的元数据部分类中的必需属性(我的印象是我必须为我希望强制执行的所有属性)但是从我的视图中POST之后控制器操作返回到与此检查结果相同的视图
// check for errors
if (!ViewData.ModelState.IsValid)
return View(invoice);
描述属性不应为null。我故意将属性的文本框发布为空,并且我没有为此属性设置自定义(手动)数据注释属性。
这是EF向导为此属性生成的代码
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.DateTime PayDate
{
get
{
return _PayDate;
}
set
{
OnPayDateChanging(value);
ReportPropertyChanging("PayDate");
_PayDate = StructuralObject.SetValidValue(value);
ReportPropertyChanged("PayDate");
OnPayDateChanged();
}
}
private global::System.DateTime _PayDate;
partial void OnPayDateChanging(global::System.DateTime value);
partial void OnPayDateChanged();
这种行为是IsNullable属性的错吗?让我明确一点,如果它确实如此,那么这是相当不错的,虽然我之前没有注意到它,并想验证这是否是正确的行为,或者我有什么东西搞砸了?
答案 0 :(得分:4)
这里有几件不同的事情。首先,EF将为数据库中的NOT NULL日期列生成DateTime属性,它将为数据库中的NULL日期列生成Nullable。这是第一点。
第二点是MVC 2在默认模型绑定器中有一些“默认”行为。也就是说,对于所有值类型,它将执行用户键入值的验证(独立于数据注释)。如果他们没有,它将显示您当前看到的验证。
这样就解释了你所看到的。但是,还有其他几点需要牢记。首先,使用[Required]属性仍然是一个好习惯,因为这允许您自定义显示给用户的错误消息。其次,对于您的视图使用视图模型而不是直接在视图中使用EF域模型通常被认为是最佳实践。所以我建议创建一个视图模型(如果您的视图模型与您的域模型匹配,您可以使用AutoMapper来映射属性),然后使用数据注释来提供对元数据的更精细控制 - 而不仅仅是验证,还有[DisplayName],[UIHint]等