2012-01-11 30 views
3

我一直在捕获异常并将用户重定向到错误页面。我传递了异常消息和返回URL来告诉用户发生了什么,并允许他们返回另一页。ASP.NET MVC - 错误声明重定向

 try 
     { 
      return action(parameters); 
     } 
     catch (Exception exception) 
     { 
      ErrorViewModel errorModel = new ErrorViewModel(); 
      errorModel.ErrorMessage = "An error occured while doing something."; 
      errorModel.ErrorDetails = exception.Message; 
      errorModel.ReturnUrl = Url.Action("Controller", "Action"); 
      return RedirectToAction("Index", "Error", errorModel); 
     } 

这似乎是方式太多的代码,以每一个动作环绕。我使用的是全局过滤错误:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     HandleErrorAttribute attribute = new HandleErrorAttribute(); 
     filters.Add(attribute); 
    } 

,我有我的web.config的设置是这样的:

<customErrors mode="On" defaultRedirect="~/Error/Unknown"> 

但是,这仅适用于未处理的异常。

我想异常,导致重定向到一个错误控制器/操作采取一个参数保存异常的细节。如果我可以在逐个行为的基础上指明返回URL,或者如果没有提供任何默认行为,那么会很好。

回答

3

这里是一个小RedirectOnErrorAttribute类我创建:

using System; 
using System.Web.Mvc; 
using MyApp.Web.Models; 

namespace MyApp.Web.Utilities 
{ 
    public class RedirectOnErrorAttribute : ActionFilterAttribute 
    { 
     /// <summary> 
     /// Initializes a new instance of a RedirectOnErrorAttribute. 
     /// </summary> 
     public RedirectOnErrorAttribute() 
     { 
      ErrorMessage = "An error occurred while processing your request."; 
     } 

     /// <summary> 
     /// Gets or sets the controller to redirect to. 
     /// </summary> 
     public string ReturnController { get; set; } 

     /// <summary> 
     /// Gets or sets the action to redirect to. 
     /// </summary> 
     public string ReturnAction { get; set; } 

     /// <summary> 
     /// Gets or sets the error message. 
     /// </summary> 
     public string ErrorMessage { get; set; } 

     /// <summary> 
     /// Redirects the user to an error screen if an exception is thrown. 
     /// </summary> 
     /// <param name="filterContext">The filter context.</param> 
     public override void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
      if (filterContext.Exception != null && !filterContext.ExceptionHandled) 
      { 
       ErrorViewModel viewModel = new ErrorViewModel(); 
       viewModel.ErrorMessage = ErrorMessage; 
       viewModel.ErrorDetails = filterContext.Exception.Message; 
       string controller = ReturnController; 
       string action = ReturnAction; 
       if (String.IsNullOrWhiteSpace(controller)) 
       { 
        controller = (string)filterContext.RequestContext.RouteData.Values["controller"]; 
       } 
       if (String.IsNullOrWhiteSpace(action)) 
       { 
        action = "Index"; 
       } 
       UrlHelper helper = new UrlHelper(filterContext.RequestContext); 
       viewModel.ReturnUrl = helper.Action(action, controller); 
       string url = helper.Action("Index", "Error", viewModel); 
       filterContext.Result = new RedirectResult(url); 
       filterContext.ExceptionHandled = true; 
      } 
      base.OnActionExecuted(filterContext); 
     } 
    } 
} 

现在,我可以装点我的所有操作是这样的:

[RedirectOnError(ErrorMessage="An error occurred while doing something.", ReturnController="Controller", ReturnAction="Action")] 
+0

这帮助......因此,该死的多 – TheGeekZn 2014-08-27 11:36:01

3

而不是在每个操作中放入try catch,您可以重写控制器的OnException事件。该事件包含所有异常细节。所有其他设置看起来都是正确的。

[HandleError] 
    public class AccountController : Controller 
    { 
     [HttpPost] 
     public ActionResult YourAction(SomeModel model) 
     { 
      //do stuff but don't catch exception 
      return View(); 
     } 
     protected override void OnException(ExceptionContext filterContext) 
     { 
      EventLog.WriteEntry("YourProjectEventName", filterContext.Exception.ToString(), EventLogEntryType.Error); 
      base.OnException(filterContext); 
     } 
}