在asp.net MVC2中将错误(异常消息)从存储库传递到控制器操作

本文关键字:存储 操作 控制器 消息 MVC2 net asp 异常 错误 | 更新日期: 2023-09-27 17:49:33

我一直在尝试开发一个应用程序,使用存储库模式,如在书呆子晚餐应用程序,但我想处理存储库中的异常,并将异常消息传递回控制器,以便我可以在一个漂亮的页面输出消息给用户。

我如何传递这个异常消息,或者甚至传递一个异常已经在存储库中发生。

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

在上面url的示例中,"_repository. net"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.}  

在asp.net MVC2中将错误(异常消息)从存储库传递到控制器操作

你可以允许你的存储库的异常落空,并覆盖你的控制器的onactionperformed方法来处理特定的错误。例子:

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

所以,一般在ASP。. NET MVC你需要处理两种错误:验证错误和系统错误。

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

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

  • 使用数据注释验证器进行验证——在这里你可以看到如何使用内置的注释属性验证简单的验证规则。
  • 使用服务层进行验证——这是一个更高级的主题,您可以在其中学习如何验证更复杂的验证规则(例如,用于相互连接的属性等)

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

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

我希望这对你有帮助!

我个人仍然喜欢由ScottGu开始的GetRuleViolations()方法,并且只会在Repository上遵循这个方法。

在控制器中,我将执行(这里是pseudo):
[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;
  }
}