public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } protected void Application_Error(object sender, EventArgs e) { var exception = Server.GetLastError(); if (exception == null) { return; } //异常发生记录日志或发送邮件 //清除异常 Server.ClearError(); //重定向 Response.Redirect("home/index"); } }
3.2捕获未匹配的路由
在路由注册列表最底端注册路由。
public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { //其他配置 routes.MapRoute( name: "MatchAll", url: "{*anyurl}", defaults: new { controller = "Error",action ="Missing" } ); } }
定义Error控制器及Missing操作
public class ErrorController : Controller { // GET: Error public ActionResult Missing() { HttpContext.Response.StatusCode = 404; //禁用IIS7默认的错误页,这样才能展示我们指定都的视图 HttpContext.Response.TrySkipIisCustomErrors = true; //也可以在此处记录日志信息 //要展示的信息 var model = ...... return View(model); } }
需要注意的是,这种方式不一定能处理所有未匹配的情形。
例如:,这个url请求说我home是存在,但是index1操作不存在,上面配置MatchAll路由无法匹配这个url。
可以匹配的情形如:,这个url能被上面配置的MatchAll路由匹配,所以可以显示Missing视图。
4实践
4.1使用HandleErrorAttribute注意要对<system.web>的<customErrors>节进行设置 。
例如:
控制器为
public class HomeController : Controller { [HandleError(ExceptionType = typeof(KeyNotFoundException), View = "Error")] public ActionResult Index() { throw new KeyNotFoundException(); return View(); } //其他控制操作 }
<system.web>的<customErrors>节
<customErrors mode="On" defaultRedirect="Error/Error2"></customErrors>
Error.cshtml文件位于Views文件夹下的子文件夹Shared文件夹下
浏览器中输入:
结果可以正常显示Error.cshtml页面,同时注意到虽然在customErrors 配置节中指定了defaultRedirect,但还是跳转到Error.cshtml页面。
将<customErrors>的mode设置为Off,则显示经典错误页。
4.2 Application_Error
代码如3.1节所示,控制器如4.1所示,<system.web>的<customErrors>节为<customErrors mode="On" defaultRedirect="Error/Error2"></customErrors>
输入:,断点调试,发现错误被HandleError拦截,Global.asax的Application_Error方法没有执行。而当输入:,Application_Error执行了。
关闭<customErrors>配置节,而不注掉控制器上的HandleErrorAttribute特性,输入:,发现Application_Error执行了。
通过上述实践,充分证明HandleErrorAttribute会拦截控制器内抛出的异常,而无法拦截无法找到资源这种异常。
4.3策略
一种常用的拦截错误信息、记录错误日志与显示自定义错误页的策略为:
1)首先配置<system.web>的<customErrors>节,注意务必设置defaultRedirect;并且定义错误控制器及相应的操作和视图。
2)定义基类控制器或自定义错误过滤器,记录异常。对于自定义错误过滤器的情形一般将其注册为全局过滤器。
3)在Global.asax中添加Application_Error方法拦截意想不到的异常并记录异常。
参考:
1.Jess Chadwick/Todd Snyder/Hrusikesh Panda,徐雷/徐扬
译。ASP.NET MVC4 Web编程
2.Jon Galloway/Phil Haack/Brad Wilson/K. Scott Allen,孙远帅/邹权译 ASP.NET MVC4 高级编程(第四版)
3.黄保翕,ASP.NET MVC4开发指南
4.蒋金楠,ASP.NET MVC4框架揭秘
5.https://www.asp.net/mvc
6.Dino Esposito著,潘丽臣译,ASP.NET MVC5编程实战