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

时间:2022-12-09 12:17:38

I prefer working with Fluent API configuration to DataAnnotation because I want to separate model from data access.

我更喜欢使用Fluent API配置到DataAnnotation,因为我想将模型与数据访问分开。

I have tried in MVC, Fluent API does not work with client side validation. Shortly speaking, is there a simple way to make Fluent API works with client side validation as DataAnnotation can do?

我在MVC中尝试过,Fluent API不能与客户端验证一起使用。简而言之,有一种简单的方法可以使Fluent API与客户端验证一起工作,因为DataAnnotation可以做到吗?

2 个解决方案

#1


35  

No. Fluent API is just mapping - correct. Data annotations are both mapping and validation - wrong. Data annotations are one of the worst features of EF code first because when used this way they couple persistence with presentation and validation logic.

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

Advice: don't use EF entities for presentation. Use special view models with data annotations and let your controller prepare view models from entities and vice-versa. Soon or later you will find situations where your validation is not 1:1 with your mapping or where your view needs more or less data than provided in entity type. Use view models and these situations will be handled by them.

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

#2


3  

I struggled with this for a while today, and this is not strictly client validation as it requires a round trip, but it does allow you to benefit from the Validation summary and messages helpers in the standard template. Within your controller action method you simply wrap your SaveChanges() call in a try - catch and add the resulting Errors to the ModelState as follows:

我今天挣扎了一段时间,这不是严格的客户端验证,因为它需要往返,但它确实允许您从标准模板中的验证摘要和消息帮助程序中受益。在您的控制器操作方法中,您只需将您的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)

This would of course require a bit more work if you are saving multiple entities here.

如果你在这里保存多个实体,这当然需要更多的工作。

Of course using a View Model objects as Ladislav suggests would be the correct approach, however I have used this to support a test UI requested for downstream systems integration testing ahead of schedule...

当然使用像Ladislav建议的View Model对象是正确的方法,但是我已经使用它来支持提前下游系统集成测试所要求的测试UI ...

#1


35  

No. Fluent API is just mapping - correct. Data annotations are both mapping and validation - wrong. Data annotations are one of the worst features of EF code first because when used this way they couple persistence with presentation and validation logic.

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

Advice: don't use EF entities for presentation. Use special view models with data annotations and let your controller prepare view models from entities and vice-versa. Soon or later you will find situations where your validation is not 1:1 with your mapping or where your view needs more or less data than provided in entity type. Use view models and these situations will be handled by them.

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

#2


3  

I struggled with this for a while today, and this is not strictly client validation as it requires a round trip, but it does allow you to benefit from the Validation summary and messages helpers in the standard template. Within your controller action method you simply wrap your SaveChanges() call in a try - catch and add the resulting Errors to the ModelState as follows:

我今天挣扎了一段时间,这不是严格的客户端验证,因为它需要往返,但它确实允许您从标准模板中的验证摘要和消息帮助程序中受益。在您的控制器操作方法中,您只需将您的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)

This would of course require a bit more work if you are saving multiple entities here.

如果你在这里保存多个实体,这当然需要更多的工作。

Of course using a View Model objects as Ladislav suggests would be the correct approach, however I have used this to support a test UI requested for downstream systems integration testing ahead of schedule...

当然使用像Ladislav建议的View Model对象是正确的方法,但是我已经使用它来支持提前下游系统集成测试所要求的测试UI ...