How i can implement Exception Filters in MVC5.
I want to throw the exception to NLog and redirect the page to a default error page which displays "Something is gone wrong"
I have a Filter class as follows
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"}
});
}
}
}
But nothing is redirecting to the page...
You could derive your own HandleErrorAttribute
public class NLogExceptionHandlerAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
// log error to NLog
base.OnException(filterContext);
}
}
Then register it globally
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new NLogExceptionHandlerAttribute());
...
}
By default, the HandleErrorAttribute
will display the Error
view located in the ~/Views/Shared
folder but if you wanted to display a specific view you can set the View
property of the attribute.
I believe it should be this code:
public class MyExceptionFilter : IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
action = "UserLogOut",
controller = "User",
area = "User"
}));
}
}
You may add an additional "if (!filterContext.ExceptionHandled)" statement before logging the values inside the result to make sure that the exception's unhandled for the moment.
Exception filters are run only when unhandled exception has been thrown inside an action method. As you asked, here is an example to redirect to another page upon exception:
public class MyExceptionAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
if(!filterContext.ExceptionHandled)
{
filterContext.Result = new RedirectResult("~/Content/ErrorPage.html");
filterContext.ExceptionHandled = true;
}
}
}
Now, to apply this filter to either controllers or individual actions, put [MyException] on them.
You may need to check the occurence of an specific Exception inside the if clause. e.g.:
if(... && filterContext.Excaption is ArgumentOutOfRangeException)
To return a View as Exception Response:
filterContext.Result = new RedirectResult("/Home/ErrorAction");
other alternatives you might use to redirect are:
- new RedirectToRouteResult{ ... }
- new ViewResult{ ... }
来源:https://stackoverflow.com/questions/24201795/how-to-use-exception-filters-in-mvc-5