2011-01-28 42 views
6

对于我的每个业务实体,我都有相应的视图模型。ASP.NET MVC:如何让我的业务规则验证泡泡到表示层?

我有一个通用的CRUD控制器,它的工作原理是这样的:

[HttpPost] 
    public virtual ActionResult Create(TViewModel model, int? id) 
    { 
     // Validate input 
     if (!ModelState.IsValid) 
      return Json(Failure(createView, model.SelectLists(repository))); 

     // Prepare Model 
     var entity = new TModel(); 

     // Add to repository 
     UpdateModel(entity); 
     repository.Add(entity); 
     repository.Save(); 
     return Json(CreateSuccess(entity)); 
    } 

我在我的视图模型属性使用数据注释,这对于简单的输入验证的伟大工程。

现在我有一个情况,我想确保重复记录不是偶然创建的。

我的第一个直觉就是把这个逻辑放到版本库的Add方法中。这个实现很简单,但是如何获取存储库来添加模型状态错误并向用户返回一些有用的信息?我觉得有必要有一个解决方案,但我没有太多的运气搜索。

感谢您的帮助!

回答

3

我会使用例外。

  • 如果一个enity加倍,则将您的自定义应用程序异常抛出在Add方法中。
  • 将Add方法包装在try块中以在Create方法中捕获此特定异常。
  • 在catch块

    try 
    { 
        repository.Add(entity); 
    } 
    catch(MyRepositoryException ex) 
    { 
        ViewData.ModelState.AddModelError(ex.Key, ex.Value.ToString(), ex.Message) 
    } 
    
    if (!ModelState.IsValid) 
          return Json(Failure(createView, model.SelectLists(repository))); 
    
+0

看起来像我在下面发布的基本的书呆子晚餐概念的一个很好的总结。正如我在我的回答中所述,我不喜欢使用异常的想法,而是主动在实体(或本例中的存储库)上调用Validate()方法。谢谢! – 2011-01-28 03:19:21

1

我讨厌回答我的问题,添加基于异常数据的模型状态错误,但我觉得我碰到我一直在寻找而寻找答案跌跌撞撞别的东西:

http://nerddinnerbook.s3.amazonaws.com/Part3.htm

看起来好像是时候了背到基础评论!我应该考虑回顾我的第一篇教程,因为当我刚开始时,我没有办法吸收所有的东西。

if (ModelState.IsValid) { 

    try { 
     dinner.HostedBy = "SomeUser"; 

     dinnerRepository.Add(dinner); 
     dinnerRepository.Save(); 

     return RedirectToAction("Details", new{id=dinner.DinnerID}); 
    } 
    catch { 
     ModelState.AddModelErrors(dinner.GetRuleViolations()); 
    } 
} 

有关实现该返回与属性名称和错误消息字符串将被添加到控制器的ModelState中,这使得这种验证出错的域模型验证教程会谈3部分我不知道我是否喜欢为违反商业规则提出例外的想法,但基本模式对我的项目来说会很有效。希望这可以帮助别人!

+0

我在catch块中编辑了代码:它应该是“ModelState.AddModelErrors ...”。对于想知道为什么ModelState中没有“AddModelErrors”方法的人来说,它是一种扩展方法。 http://forums.asp.net/t/1409804.aspx/1 – Rohit 2013-08-06 16:31:03

1

您的方法的替代方案是使用ModelStateWrapper实现IValidationDictionary的想法。它基本上解耦了modelState,但仍然让您的存储库/服务与错误字典进行交互。这种方式的错误处理都是通过接口完成的,不需要引用任何MVC特定的数据对象。

有好就可以了书面记录在这里:http://www.asp.net/mvc/tutorials/validating-with-a-service-layer-cs,但其基本思想是:

public MyController() 
{ 
    repository = new MyRepository(new ModelStateWrapper(this.ModelState)); 
} 

2)地址:

1)控制器的初始化过程中通过你的ModelStateWrapper的实例来存储库错误是你的资料库里面:

_validatonDictionary.AddError("Name", "Name is required."); 

3)处理错误就像你通常会在你的控制器:

if (!repository.Save()) 
    return View();