ASP.net MVC – 自定义HandleErrorfilter – 基于exceptiontypes指定视图
我在我的MVC应用程序inheritanceHandleErrorAttribute
,所以我可以logging错误:
public class HandleAndLogErrorAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); if( filterContext.Exception != null ) { // log here } } }
我将其添加为全局filter:
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleAndLogErrorAttribute()); }
是否有可能为特定的exceptiontypes指定自定义视图? 例如:
if( filterContext.Exception is DivideByZeroException ) { // how do i specify that the view should be DivideByZero? }
- 创build一个inheritance
HandleErrorAttribute
的新filter(或直接实现IExceptionFilter) - 注册在global.asax(通过replace
filters.Add(new HandleError());
):
这是我创build的一个filter,它试图根据特定的HTTP状态代码查找一个视图:
public class MyErrorHandler : FilterAttribute, IExceptionFilter { public void OnException(ExceptionContext filterContext) { if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled) return; var statusCode = (int) HttpStatusCode.InternalServerError; if (filterContext.Exception is HttpException) { statusCode = filterContext.Exception.As<HttpException>().GetHttpCode(); } else if (filterContext.Exception is UnauthorizedAccessException) { //to prevent login prompt in IIS // which will appear when returning 401. statusCode = (int)HttpStatusCode.Forbidden; } _logger.Error("Uncaught exception", filterContext.Exception); var result = CreateActionResult(filterContext, statusCode); filterContext.Result = result; // Prepare the response code. filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = statusCode; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; } protected virtual ActionResult CreateActionResult(ExceptionContext filterContext, int statusCode) { var ctx = new ControllerContext(filterContext.RequestContext, filterContext.Controller); var statusCodeName = ((HttpStatusCode) statusCode).ToString(); var viewName = SelectFirstView(ctx, "~/Views/Error/{0}.cshtml".FormatWith(statusCodeName), "~/Views/Error/General.cshtml", statusCodeName, "Error"); var controllerName = (string) filterContext.RouteData.Values["controller"]; var actionName = (string) filterContext.RouteData.Values["action"]; var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); var result = new ViewResult { ViewName = viewName, ViewData = new ViewDataDictionary<HandleErrorInfo>(model), }; result.ViewBag.StatusCode = statusCode; return result; } protected string SelectFirstView(ControllerContext ctx, params string[] viewNames) { return viewNames.First(view => ViewExists(ctx, view)); } protected bool ViewExists(ControllerContext ctx, string name) { var result = ViewEngines.Engines.FindView(ctx, name, null); return result.View != null; } }