【问题标题】:ASP.NET MVC - Declarative Redirect On ErrorASP.NET MVC - 错误时的声明性重定向
【发布时间】:2012-02-08 00:36:47
【问题描述】:

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

        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,或者如果没有提供默认值,那就太好了。

【问题讨论】:

    标签: asp.net-mvc redirect error-handling declarative


    【解决方案1】:

    这是我创建的一个 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")]
    

    【讨论】:

    • 这帮助了...该死的
    【解决方案2】:

    您可以覆盖控制器的 OnException 事件,而不是在每个操作中都放置一个 try catch。该事件包含所有异常详细信息。你们所有的其他设置看起来都正确。

        [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);
           }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 2014-06-20
      • 1970-01-01
      • 2018-05-02
      • 1970-01-01
      • 2021-09-09
      相关资源
      最近更新 更多