【问题标题】:Passing Errors (Exception Messages) from Repository to Controller Action in asp.net MVC2在 asp.net MVC2 中将错误(异常消息)从存储库传递到控制器操作
【发布时间】:2012-08-27 21:43:48
【问题描述】:

我一直在尝试使用 Nerd Dinner 应用程序中的存储库模式开发应用程序,但是我想处理存储库中的异常并将异常消息传递回控制器,以便我可以很好地输出消息页面给用户。

我如何传回这个异常消息,甚至传回存储库中发生了异常。

http://www.asp.net/ajaxlibrary/jquery_errors.ashx

在上面 url 的以下示例中,“_repository.HasErrors”被用作检查,但我想知道它在 C# 存储库中的实现是什么,因为我不知道它是如何实现的,也不知道它是否也可能会收到错误消息。

01.// GET: /HandlejQueryErrors/Contact/Create   
02.public ActionResult Create()   
03.{   
04.    return View();   
05.}  
06.  
07.// POST: /HandlejQueryErrors/Contact/Create   
08.[HttpPost]   
09.public ActionResult Create(ContactViewModel viewModel)   
10.{   
11.    var response = new AjaxResponseViewModel();  
12.  
13.    try  
14.    {   
15.        var contact = _repository.SaveOrUpdate(viewModel);   
16.        if (!_repository.HasErrors)   
17.        {   
18.            response.Success = true;   
19.            response.Message = "Your contact was successfully created!";   
20.        }    
21.        else  
22.        {   
23.            response.Message = "There was an error updating your contact!";   
24.        }   
25.    }   
26.    catch (Exception exception)   
27.    {   
28.        response.Success = false;   
29.        response.Messages exception.Message;    
30.    }  
31.  
32.    return Json(response);   
33.}  

提前致谢。

【问题讨论】:

    标签: c# asp.net asp.net-mvc-2 repository repository-pattern


    【解决方案1】:

    您可以允许存储库的异常通过,并覆盖控制器的 OnActionExecuted 方法来为您处理特定错误。示例:

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext.Exception is RepositoryException)
        {
            filterContext.ExceptionHandled = true;
    
            filterContext.Result = View("Exception", filterContext.Exception);
        }
    
        base.OnActionExecuted(filterContext);
    }
    

    【讨论】:

    • 那么 [HandleError] 属性是否会做类似于您提议的事情?您在上面使用的 RepositoryException 的定义是什么?
    • 此外,存储库异常是您希望从存储库收到的任何异常。
    【解决方案2】:

    因此,在 ASP.NET MVC 中,您通常需要处理两种错误:验证错误和系统错误。

    对于系统错误,由于某些系统规则违反(例如插入期间数据库中的外键约束违反)而发生的错误,您应该使用 try-catch 运算符,然后以某种方式将它们传递给视图以显示给用户.

    对于验证错误,您应该阅读 ASP.NET MVC 验证:

    因此,作为结论,请考虑将域/业务功能的关注点与验证相关的关注点分开。他们应该拥有的唯一共同点(在完美场景中)是显示验证结果的视图。

    我个人(采用第二种方法)甚至保存验证,以便验证实现了解域/业务逻辑并对其进行操作以验证所有规则。在验证结束时,如果满足所有规则,则尝试保存数据,如果不成功则返回验证错误消息。这也是进一步发展甚至本地化您的自定义验证消息的良好开端。

    我希望这会有所帮助!

    【讨论】:

    • 是的,这正是我想做的事情,但是如果我在所有存储库方法中使用 try catch 来捕获系统错误,我如何将该异常传递回调用存储库方法,以便我可以告诉用户他们是系统错误?
    • 您应该在具有返回异常信息的机制的方法中使用 try-catch。我认为这不应该发生在存储库中,它们不应该捕获系统异常;或者,更好的是,他们应该捕获并抛出另一个带有更清晰错误消息的异常。我建议在验证层中使用这种方法,您可以在其中捕获异常并返回验证错误以及此验证期间发生的所有验证错误。控制器可以将所有这些错误放入模型状态错误中,以便视图可以将它们显示为摘要。
    【解决方案3】:

    我个人仍然喜欢由 ScottGu 发起的 GetRuleViolations() 方法,并且会在存储库中简单地遵循这一点。

    在控制器中我会做(这里是伪):

    [HttpPost]
    public ActionResult ControllerAction(MyViewModel viewModel)
    {
      ModelState.AddRuleViolations(viewModel.GetRuleViolations);
    
      if (!ModelState.IsValid)
      {
        return View();
      }
    
      // Perform repository action (pseudo code to follow)
      _repository.ClearErrorState();
      _repository.DoSomething();
      ModelState.AddRuleViolation(repository.GetRuleViolations());
    
      if (!ModelState.IsValid)
      {
        return View();
      }
    
      return RedirectToAction("Foo","Bar");
    }
    
    class Repository
    {
      List<RuleViolation> _errors = new List<RuleViolation>();
    
      public void ClearErrorState()
      {
        _errors.Clear();
      }
    
      public void DoSomething(...)
      {
         try
         {
           DoSomthingThatFails();
         }
         catch (Exception ex)
         {
           _errors.Add(new RuleViolation(null, "Error while saving customer");
           _errors.Add(new RuleViolation("SSN", "SSN must be unique"); // This one I struggle with as bad design, tying UI element to data elements is bad, so generally I try to prevent everything when checking the viewmodel and only catch general (unforeseen) errors here.
         }
      }
    
      public IEnumerable<RuleViolation> GetRuleViolations()
      {
        return _errors;
      }
    }
    

    【讨论】:

    • 如果出现此系统错误,将与数据验证错误混合在一起。验证数据注释处理 MVC2 中的验证错误。是否可以做类似的事情但不添加到 RuleViolations 并添加到不同的列表而不是系统错误?任何想法 _repository.HasErrors 的实现实际上可能来自上面的博客文章?因为我猜这可能是某种列表?他似乎在 _repository.SaveOrUpdate(viewModel) 之后使用它,那么 SaveOrUpdate() 中是否有什么特别之处,您认为该方法的实现是什么?
    猜你喜欢
    • 2021-06-22
    • 2013-10-05
    • 2018-11-23
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 2014-12-23
    相关资源
    最近更新 更多