ASP.net MVC - 自定义 HandleError 过滤器 - 根据异常类型指定视图 [英] ASP.net MVC - Custom HandleError Filter - Specify View based on Exception Type
本文介绍了ASP.net MVC - 自定义 HandleError 过滤器 - 根据异常类型指定视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我在我的 MVC 应用程序中继承了 HandleErrorAttribute
以便我可以记录错误:
I am inheriting the HandleErrorAttribute
in my MVC application so I can log the error:
public class HandleAndLogErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
base.OnException(filterContext);
if( filterContext.Exception != null )
{
// log here
}
}
}
我将此添加为全局过滤器:
I'm adding this as a global filter:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleAndLogErrorAttribute());
}
是否也可以为特定异常类型指定自定义视图?例如:
Is it possible to specify a custom view for specific exception types as well? For example:
if( filterContext.Exception is DivideByZeroException )
{
// how do i specify that the view should be DivideByZero?
}
推荐答案
- 创建一个继承
HandleErrorAttribute
的新过滤器(或直接实现IExceptionFilter) - 在 global.asax 中注册(通过替换
filters.Add(new HandleError());
):
- Create a new filter which inherits
HandleErrorAttribute
(or implements IExceptionFilter directly) - Register it in global.asax (by replacing
filters.Add(new HandleError());
):
这是我创建的一个过滤器,它尝试根据特定的 HTTP 状态代码查找视图:
Here is a filter that I've created that tries to find a view per specific HTTP status code:
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;
}
}
这篇关于ASP.net MVC - 自定义 HandleError 过滤器 - 根据异常类型指定视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文