无论是桌面程序还是web程序,异常处理都是必须的. 一般的处理方式是, 捕获异常,然后记录异常的详细信息到文本文件或者数据库中. 要让HandleErrorAttribute特性工作,需要修改我们的Web.config文件配置 </system.web> ... <customErrors mode="On" defaultRedirect="Error.htm"/> </system.web> HandleErrorAttribute 特性能够在Action, Controller, 和Global 三个级别中使用 1. 在 Action方法级别使用在Action方法上使用,非常简单,只需要在方法头上加上HandleError特性,告诉MVC如果该Action方法出现异常,交由HandleError特性处理 [HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")] public ActionResult Index(int id) { var db = new MyDataContext(); return View("Index", db.Categories.Single(x => x.Id == id)); } 上面例子中,当在运行Index方法的时候,如果发生数据库异常, MVC 将会显示 2. 在 Controller级别使用同Action相似,只需要简单的将改特性放到controller类头上,告诉MVC如果该Controller中的Action方法出现异常,都交由HandleError特性处理 [HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")] public class HomeController : Controller { /* Controller Actions with HandleError applied to them */ } 3. 在Global级别上使用我们也可以把HandleError特性注册到全局级别,使得它在全局范围中起作用。全局范围起作用的意思是,项目中的所有controller都 使用HandleError处理异常。要注册global级别, 在项目的文件夹App_Start中打开 FilterConfig.cs文件找到RegisterGlobalFilters方法 默认的, ASP.NET MVC已经把HandleError特性注册成global. 这里你可以添加自定义的filter public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute { ExceptionType = typeof(System.Data.DataException), View = "DatabaseError" }); filters.Add(new HandleErrorAttribute()); //by default added } 一定要注意, 全局的filter是依照它们注册的顺序执行的。所以如果有多个filter, 要在注册其它fileter之前注册error filter 当然,你也可以在注册global filter的时候,指定它们的顺序。下面的代码是指定了顺序的,和上面的等价。 public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute(),2); //by default added filters.Add(new HandleErrorAttribute { ExceptionType = typeof(System.Data.DataException), View = "DatabaseError" },1); } 4. 使用MVC默认的HandleError特性的局限性
5. 扩展HandleErrorAttribute我们可以通过继承 1 public class CustomHandleErrorAttribute : HandleErrorAttribute 2 { 3 public override void OnException(ExceptionContext filterContext) 4 { 5 if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) 6 { 7 return; 8 } 9 if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500) 10 { 11 return; 12 } 13 if (!ExceptionType.IsInstanceOfType(filterContext.Exception)) 14 { 15 return; 16 } 17 // if the request is AJAX return JSON else view. 18 if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") 19 { 20 filterContext.Result = new JsonResult 21 { 22 JsonRequestBehavior = JsonRequestBehavior.AllowGet, 23 Data = new 24 { 25 error = true, 26 message = filterContext.Exception.Message 27 } 28 }; 29 } 30 else 31 { 32 var controllerName = (string)filterContext.RouteData.Values["controller"]; 33 var actionName = (string)filterContext.RouteData.Values["action"]; 34 var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); 35 filterContext.Result = new ViewResult 36 { 37 ViewName = View, 38 MasterName = Master, 39 ViewData = new ViewDataDictionary(model), 40 TempData = filterContext.Controller.TempData 41 }; 42 } 43 // log the error by using your own method 44 LogError(filterContext.Exception.Message, filterContext.Exception); 45 filterContext.ExceptionHandled = true; 46 filterContext.HttpContext.Response.Clear(); 47 filterContext.HttpContext.Response.StatusCode = 500; 48 filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; 49 } 50 } 以上就是在MVC开发中,自己常用到的一些小技巧,希望对大家有帮助。 |
|