繁体   English   中英

ASP.NET MVC:如何让我的业务规则验证冒泡到表示层?

[英]ASP.NET MVC: How can I get my business rule validation to bubble up to the presentation layer?

对于我的每个业务实体,我都有一个相应的视图模型。

我有一个通用的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方法中。 这个实现很简单,但是如何让存储库添加模型状态错误并将一些有用的信息返回给用户? 我觉得必须有一个解决方案,但我没有太多的运气搜索。

谢谢你的帮助!

我会使用例外。

  • 如果enity加倍,则在Add方法中抛出自定义应用程序异常。
  • 将try方法包装在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))); 

我讨厌回答我自己的问题,但我想我在寻找其他东西时偶然发现了我正在寻找的答案:

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

看起来是时候回归基础了! 我应该想回去看看我的第一个教程,因为在我刚开始的时候,我无法吸收所有内容。

本教程的第3部分讨论了实现域模型验证,该验证返回带有属性名称和错误消息字符串的错误,这些字符串将添加到控制器的ModelState中,从而允许进行这种验证:

if (ModelState.IsValid) {

    try {
        dinner.HostedBy = "SomeUser";

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

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

我不知道我是否喜欢为违反业务规则而引发异常的想法,但基本模式对我的项目很有用。 希望这有助于其他人!

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

这里有一篇很好的文章: http//www.asp.net/mvc/tutorials/validating-with-a-service-layer-cs ,但基本思路是:

1)在控制器初始化期间将ModelStateWrapper的实例传递给存储库:

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

2)在存储库中添加错误:

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

3)处理您通常在控制器中出现的错误:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM