为什么服务器端验证不能在我的 ASP.Net MVC3 应用程序中与 Entity Framework 一起工作?

Why isn't server side validation working in my ASP.Net MVC3 application with Entity Framework?

我有一个使用从数据库生成的实体的 ASP.NET MVC3 应用程序。每个实体还有一个单独的部分类,它使用 MetadataType 属性将每个实体与一个装饰有许多验证属性的类相关联(见下文)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[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; }
    }
}

我的控制器代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
[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 并将我返回到索引页面。

谁能提供有关如何使用 Entity Framework 实体进行服务器端验证的任何建议?

更新:

看来这个问题和我的差不多。这篇文章的作者似乎已经解决了这个问题,但却没有提及他们是如何解决这个问题的……


我找到了解决这个问题的另一种方法。因为我真的不想将我的属性设置为可为空,所以我添加了以下内容:

1
[DisplayFormat(ConvertEmptyStringToNull = false)]

将以下注释添加到模型属性也可以修复错误。


经过进一步调查,当默认模型绑定器尝试将用户输入值(在本例中为 Null)绑定到实体时,我的实体类(继承自 ObjectContext)抛出了 ConstraintException,似乎出现了我的问题属性。

我可以看到 2 种可能的解决方案:

  • 放松对我的数据库表的约束(我不想这样做)。
  • 使实体字段可为空(使用实体设计器将可为空的属性设置为是)
  • 我已经使用并测试了第二个选项,并且可以确认服务器端验证现在按预期工作。

    在研究这个问题的解决方案时,我得出的结论是,问题是由于我的实体继承自 ObjectContext,这是一个相当重的类。我发现了很多使用代码优先方法的教程。在这种情况下,实体类将继承自更轻量级的 DbContext,因此我想这可以被视为问题的第三种解决方案。