C# 如何使Fluent API配置与MVC客户端验证一起工作?

C# 如何使Fluent API配置与MVC客户端验证一起工作?,c#,asp.net,asp.net-mvc-3,entity-framework,ef-code-first,C#,Asp.net,Asp.net Mvc 3,Entity Framework,Ef Code First,与DataAnnotation相比,我更喜欢使用Fluent API配置,因为我希望将模型与数据访问分开 我曾在MVC中尝试过,Fluent API不适用于客户端验证。简而言之,有没有一种简单的方法可以让Fluent API像DataAnnotation那样与客户端验证一起工作?没有。Fluent API只是映射-正确。数据注释是映射和验证-错误。数据注释首先是EF代码最糟糕的特性之一,因为当以这种方式使用时,它们将持久性与表示和验证逻辑结合起来 建议:不要使用EF实体进行演示。使用带有数据注释

与DataAnnotation相比,我更喜欢使用Fluent API配置,因为我希望将模型与数据访问分开


我曾在MVC中尝试过,Fluent API不适用于客户端验证。简而言之,有没有一种简单的方法可以让Fluent API像DataAnnotation那样与客户端验证一起工作?

没有。Fluent API只是映射-正确。数据注释是映射和验证-错误。数据注释首先是EF代码最糟糕的特性之一,因为当以这种方式使用时,它们将持久性与表示和验证逻辑结合起来


建议:不要使用EF实体进行演示。使用带有数据注释的特殊视图模型,让控制器从实体准备视图模型,反之亦然。不久或稍后,您将发现您的验证与映射不是1:1的情况,或者视图需要比实体类型中提供的数据更多或更少的数据。使用视图模型,这些情况将由他们来处理。

我今天为此奋斗了一段时间,这并不是严格意义上的客户端验证,因为它需要往返,但它确实允许您从标准模板中的验证摘要和消息帮助器中获益。在控制器操作方法中,只需将
SaveChanges()
调用包装在try-catch中,并将结果错误添加到
ModelState
中,如下所示:

try {

    //This does not pick up fluent validation failures
    if (ModelState.IsValid) {
        db.Entity.Add(entity);
        db.SaveChanges();
        //Users want to create loads of my entities without seeing the index...
        return RedirectToAction("Create");
    }

} catch (DbEntityValidationException e) {

    //Log errors
    foreach (var result in e.EntityValidationErrors) {
        foreach(var error in result.ValidationErrors){
            ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
        }
    }

}

//return to view with current model + validation errors 
return View(entity)
如果在这里保存多个实体,这当然需要更多的工作


当然,按照Ladislav的建议使用视图模型对象是正确的方法,但是我已经使用它来支持提前进行下游系统集成测试所需的测试UI…

为什么EF甚至需要像“HasMaxLength”这样的映射?如果该值较长,则如果尝试写入,SQL server将拒绝该值,并且这与读取无关,因为
string
type没有长度限制。那么这个映射到底是为了什么呢?我知道这是一个老问题,但我想我会为未来的读者补充一下。一个原因是,如果先使用代码然后创建数据库,那么fluent api/数据注释将用于构建create table语句,其中需要知道所需的长度等等。