Filters enable running custom pre and post processing logic for action methods. Filters can be applied to controllers or actions as attributes
The ASP.NET MVC framework provides five types of filters.
- Authentication filters (introduced in MVC5)
- Authorization filters
- Action filters
- Result filters
- Exception filters
Authentication filters
Authentication filters run before any other filters and it's implement IAuthenticationFilter interface is used to create CustomAuthentication filter. The IAuthenticationFilter interface declares two methods: OnAuthentication and OnAuthenticationChallenge
public class BasicAuthenticationFilter : ActionFilterAttribute, IAuthenticationFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
Debug.WriteLine("OnAuthentication");
if (!filterContext.Principal.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new { controller = "Home", action = "Login" }));
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
Debug.WriteLine("OnAuthenticationChallenge");
}
}
Authorization filters
Authorization filters implement IAuthorizationFilter and make security decisions about whether to execute an action method, such as performing authentication or validating properties of the request. The AuthorizeAttribute class and the RequireHttpsAttribute class are examples of an authorization filter.public class BasicAuthorizationFilter : ActionFilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
Debug.WriteLine("OnAuthorization");
//todo: business authorization validation here
}
}
}
Action filters
Action filters implement IActionFilter and wrap the action method execution. The IActionFilter interface declares two methods: OnActionExecuting and OnActionExecuted.OnActionExecuting runs before the action method.
OnActionExecuted runs after the action method and can perform additional processing, such as providing extra data to the action method, inspecting the return value, or canceling execution of the action method.
Example 1
public class BasicActionFilter : FilterAttribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
Debug.WriteLine("OnActionExecuting");
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
Debug.WriteLine("OnActionExecuted");
}
}
Example 2: Converting comma separated parameter value in array
public class ParameterConverterActionFilter : FilterAttribute, IActionFilter
{
private readonly string _parameterName;
public ParameterConverterActionFilter(string parameterName)
{
_parameterName = parameterName;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
Debug.WriteLine("OnActionExecuting");
var valueProviderResult = filterContext.Controller.ValueProvider.GetValue(_parameterName);
if (valueProviderResult != null)
{
var orders = valueProviderResult.AttemptedValue.Split(',');
filterContext.ActionParameters[_parameterName] = Array.ConvertAll(orders, s => int.Parse(s));
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
Debug.WriteLine("OnActionExecuted");
}
}
ref: www.prideparrot.com
Example 3: log the performance of the action.
public class DurationAttribute : ActionFilterAttribute
{
private Stopwatch watch;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
watch = Stopwatch.StartNew();
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
watch.Stop();
filterContext.HttpContext.Response
.Write(string.Format("<br/><br/>Elapsed time: {0}",
watch.Elapsed.TotalSeconds));
}
}
ref: www.prideparrot.com
Result filters
Result filters implement IResultFilter and wrap execution of the ActionResult object. IResultFilter declares two methods: OnResultExecuting and OnResultExecuted. OnResultExecuting runs before the ActionResult object is executed. OnResultExecuted runs after the result and can perform additional processing of the result, such as modifying the HTTP response. The OutputCacheAttribute class is one example of a result filter.Example 1:
public class BasicResultFilter:FilterAttribute, IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
Debug.WriteLine("OnResultExecuting");
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
Debug.WriteLine("OnResultExecuted");
}
}
Example 2:
public class CopyrightResultFilter:FilterAttribute, IResultFilter
{
public void OnResultExecuting(ResultExecutingContext filterContext)
{
Debug.WriteLine("OnResultExecuting");
var jsonResult = (JsonResult)filterContext.Result;
var model = (Person)jsonResult.Data;
model.copyright = "asp.net";
}
public void OnResultExecuted(ResultExecutedContext filterContext)
{
Debug.WriteLine("OnResultExecuted");
}
}
public class HomeController : Controller
{
[CopyrightResultFilter]
public JsonResult AdvancedResultFilterExample()
{
var person = new Person { name = "John", age = 30, car = "Fiat" };
return Json(person, JsonRequestBehavior.AllowGet);
}
}
Exception filters
Exception filters implement IExceptionFilter and execute if there is an unhandled exception thrown during the execution of the ASP.NET MVC pipeline. Exception filters can be used for tasks such as logging or displaying an error page. The HandleErrorAttribute class is one example of an exception filter. public class BasicExceptionFilter : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
Debug.WriteLine("OnException");
if (filterContext.Exception != null)
{
string msg = filterContext.Exception.Message;
Debug.WriteLine(msg);
filterContext.ExceptionHandled = true;
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new {area="FilterExample", controller = "Home", action = "Error" }));
}
}
}
Each different type of filter is executed in a particular order. If you want to control the order in which filters of the same type are executed then you can set a filter's Order property.
The base class for all action filters is the FilterAttribute class. If you want to implement a particular type of filter, then you need to create a class that inherits from the base Filter class and implements one or more of the IAuthenticationFilter, IAuthorizationFilter, IActionFilter, IResultFilter, or IExceptionFilter interfaces.