我如何在MVC5中实现异常过滤器。
我想将异常抛给NLog,并将页面重定向到默认错误页面,显示"出错了"
我有一个Filter类,如下所示
using System;
using System.Diagnostics;
using System.Security.Policy;
using System.Web.Mvc;
using System.Web.Mvc.Filters;
using System.Web.Routing;
using System.Web.UI.WebControls;
using Delivros.UI.Controllers;
using Delivros.UI.Areas.User.ViewModel;
using System.Web;
namespace Delivros.UI.Filters
{
public class CustomAuthenticationFilter : IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
Debug.WriteLine("OnAuthenticationChallenge : MyAuthenticationFilter");
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MyAuthorizationFilter : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.RequestContext.HttpContext.Request.Cookies[System.Configuration.ConfigurationManager.AppSettings[Convert.ToString(CookieField.cookieName)]] == null)
{
}
else
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "User" },
{ "action", "UserRegistration" } ,
{"Area","User"}
});
}
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class CustomActionFilter : ActionFilterAttribute
{
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuted(filterContext);
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "User" },
{ "action", "UserRegistration" } ,
{"Area","User"}
});
// ActionResult home = new HomeController().Index();
}
}
public class MyResultFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
}
}
public class MyExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "controller", "User" },
{ "action", "UserLogOut" } ,
{"Area","User"}
});
}
}
}
但没有任何内容重定向到页面......
答案 0 :(得分:20)
您可以派生自己的HandleErrorAttribute
public class NLogExceptionHandlerAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
// log error to NLog
base.OnException(filterContext);
}
}
然后全局注册
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new NLogExceptionHandlerAttribute());
...
}
默认情况下,HandleErrorAttribute
会显示位于Error
文件夹中的~/Views/Shared
视图,但如果您想要显示特定视图,则可以设置View
属性属性。
答案 1 :(得分:1)
我认为应该是这段代码:
salary
}
您可以添加额外的" if(!filterContext.ExceptionHandled)"在记录结果中的值之前的语句,以确保暂时未处理异常。
答案 2 :(得分:0)
仅当在操作方法内引发未处理的异常时,才运行异常过滤器。如您所问,这是一个异常时重定向到另一个页面的示例:
public class MyExceptionAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if(!filterContext.ExceptionHandled)
{
filterContext.Result = new RedirectResult("~/Content/ErrorPage.html");
filterContext.ExceptionHandled = true;
}
}
}
现在,要将此过滤器应用于控制器或单个动作,请在其上放置[MyException]。
您可能需要检查if子句中特定异常的发生。 例如:
if(... && filterContext.Excaption is ArgumentOutOfRangeException)
要返回“视图作为异常响应”:
filterContext.Result = new RedirectResult("/Home/ErrorAction");
您可能会使用的其他替代方法是:
答案 3 :(得分:0)
以下为我工作。需要注意的几件事1)RedirectResult指向控制器动作,而不是视图2)您需要设置filterContext.ExceptionHandled = true;否则您的例外视图/页面将不会显示。
public class ErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
Log.Logger.Error(filterContext.Exception, "An Unhandled exeption occured durring the execution of a request");
filterContext.Result = new RedirectResult("~/MyControler/MyErrorAction");
filterContext.ExceptionHandled = true;
}
}
当然,您还需要使用Global.asax中的GlobalFilters对象注册Error属性,如下所示。
protected void Application_Start()
{
GlobalFilters.Filters.Add(new ErrorAttribute());
...
}