将错误(异常消息)从存储库传递到asp.net MVC2中的Controller Action

时间:2011-04-06 22:23:10

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

我一直在尝试使用像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.}  

提前致谢。

3 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:1)

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

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

对于验证错误,您应该阅读有关ASP.NET MVC验证的信息:

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

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

我希望这有帮助!

答案 2 :(得分:0)

我个人仍然喜欢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;
  }
}