我有一个ASP。NET MVC3应用程序,它使用从数据库生成的实体。每个实体也有一个单独的部分类,它使用MetadataType属性将每个实体与一个用许多验证属性装饰的类关联起来(见下文)。
[MetadataType(typeof(Drawing.Metadata))]
public partial class Drawing
{
private sealed class Metadata
{
[Required]
[StringLength(50, MinimumLength = 3, ErrorMessage = "Drawing numbers must be between {2} and {1} characters in length.")]
[DisplayName("Drawing number")]
public string Number { get; set; }
[Required]
[StringLength(255, MinimumLength = 3, ErrorMessage = "Drawing titles must be between {2} and {1} characters in length.")]
public string Title { get; set; }
}
}
我的控制器代码看起来像这样:
[HttpPost]
public ActionResult Create(Drawing drawing)
{
if (ModelState.IsValid)
{
// Save to database here...
return RedirectToAction("Index");
}
else
{
return View(drawing);
}
}
我已经使用Visual Studio模板来创建视图来添加、编辑和删除实体(设计器代码没有被改变)。
我遇到的问题是,当我创建一个实体时,只有当我启用客户端验证时,验证才有效。如果我关闭客户端验证,那么ModelState。IsValid似乎总是返回true,并将我返回到索引页。
谁能提供关于如何获得服务器端验证与实体框架实体工作的任何建议?
更新:
这个问题似乎和我的问题很相似。这篇文章的作者似乎已经解决了这个问题,但却没有提及如何他们解决了这个问题…我找到了另一个解决这个问题的方法。因为我不想将属性设置为可空,所以我添加了以下内容:
[DisplayFormat(ConvertEmptyStringToNull = false)]
将以下注释添加到模型属性中也可以修复错误。
经过进一步调查,似乎我的问题是由于我的实体类(继承自ObjectContext)抛出的ConstraintException当默认模型绑定器试图将用户输入值(在这种情况下为Null)绑定到实体属性。
我可以看到两个可能的解决方案:
- 放宽对我的数据库表的约束(我不想这样做)。
- 使实体字段为空(使用实体设计器将nullable属性设置为yes)
我已经使用并测试了第二个选项,并且可以确认服务器端验证现在按预期工作。
在研究这个问题的解决方案时,我得出的结论是,这个问题是由于我的实体继承了ObjectContext,这是一个相当重的类。我发现了很多使用代码优先方法的教程。在这种情况下,实体类将继承DbContext,这是更轻量的,所以我想这可以被认为是问题的第三个解决方案。