在MVC未处理的异常上从Global.asax重定向到共享错误视图

时间:2014-09-08 09:52:56

标签: asp.net-mvc asp.net-mvc-5

我一直在阅读有关在ASP.MVC中执行错误处理的不同方法。我知道控制器中的try/catch,以及控制器级的[HandleError]

但是,我正在尝试对应用程序中可能出现任何地方的未处理异常执行全局错误处理(哇 - 我们从未期望用户这样做!事物类型)。结果是将电子邮件发送给开发人员:

这很好用:

protected void Application_Error()
{
    Exception last_ex = Server.GetLastError();
    Server.ClearError();
    // send email here...
    Response.Redirect("/Login/Login");
}

在应用程序的其他地方,如果控制器发生错误,我们有这个逻辑在错误视图中提供了一个友好的错误:

错误模型

namespace My.Models
{
    public class ErrorViewModel
    {
        public string Summary { get; set; }
        public string Description { get; set; }
    }
}

控制器代码

if(somethingBad){
    return View("Error", new ErrorViewModel { Summary = "Summary here", Description = "Detail here" });
}

我的问题是,是否可以重定向到从Global.asax中传递ErrorViewModel的错误视图,例如。

// send email here...
Response.MethodToGetToView(new ErrorViewModel { Summary = "Error", Description = ex.Message });

1 个答案:

答案 0 :(得分:4)

从Application_Error方法中,您可以执行以下操作:

RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
routeData.Values.Add("action","Error500");
routeData.Values.Add("Summary","Error");
routeData.Values.Add("Description", ex.Message);
IController controller = new ErrorController()
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));

这会将您在此处指定的操作结果中的视图返回给用户的浏览器,因此您需要一个控制器&返回所需错误视图的操作结果(本例中为Error / Error500)。它不是重定向,所以在技术上更正确(如果发生错误,你应该立即返回HTTP 500状态,而不是通常做的302然后是500)。

此外,如果您想从所有网址(不仅仅是与路线匹配的网址)捕获所有404,您可以将以下路线添加到路线配置的末尾

routes.MapRoute("CatchAllUrls", "{*url}", new { controller = "Error", action = "Error404" }, new string[] { "MyApp.Controllers" });