Wednesday, March 18, 2015

Action Filters in MVC

MVC :: Understanding Action Filters
The goal of this tutorial is to explain action filters. An action filter is an attribute that you
can apply to a controller action -- or an entire controller -- that modifies the way in which
the action is executed. The ASP.NET MVC framework includes several action filters:
• OutputCache – This action filter caches the output of a controller action for a
specified amount of time.
• HandleError – This action filter handles errors raised when a controller action
executes.
• Authorize – This action filter enables you to restrict access to a particular user or
role.
You also can create your own custom action filters. For example, you might want to create a
custom action filter in order to implement a custom authentication system. Or, you might
want to create an action filter that modifies the view data returned by a controller action.
In this tutorial, you learn how to build an action filter from the ground up. We create a Log
action filter that logs different stages of the processing of an action to the Visual Studio
Output window.
Using an Action Filter
An action filter is an attribute. You can apply most action filters to either an individual
controller action or an entire controller.
For example, the Data controller in Listing 1 exposes an action named Index() that returns
the current time. This action is decorated with the OutputCache action filter. This filter
causes the value returned by the action to be cached for 10 seconds.
Listing 1 – Controllers\DataController.cs
using System;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
public class DataController : Controller
{
[OutputCache(Duration=10)]
public string Index()
{
return DateTime.Now.ToString("T");
}
}
}
If you repeatedly invoke the Index() action by entering the URL /Data/Index into the
address bar of your browser and hitting the Refresh button multiple times, then you will see
the same time for 10 seconds. The output of the Index() action is cached for 10 seconds
(see Figure 1).
Figure 1 – Cached time
In Listing 1, a single action filter – the OutputCache action filter – is applied to the Index()
method. If you need, you can apply multiple action filters to the same action. For example,
you might want to apply both the OutputCache and HandleError action filters to the same
action.
In Listing 1, the OutputCache action filter is applied to the Index() action. You also could
apply this attribute to the DataController class itself. In that case, the result returned by any
action exposed by the controller would be cached for 10 seconds.
The Different Types of Filters
The ASP.NET MVC framework supports four different types of filters:
1. Authorization filters – Implements the IAuthorizationFilter attribute.
2. Action filters – Implements the IActionFilter attribute.
3. Result filters – Implements the IResultFilter attribute.
4. Exception filters – Implements the IExceptionFilter attribute.
Filters are executed in the order listed above. For example, authorization filters are always
executed before action filters and exception filters are always executed after every other
type of filter.
Authorization filters are used to implement authentication and authorization for controller
actions. For example, the Authorize filter is an example of an Authorization filter.
Action filters contain logic that is executed before and after a controller action executes. You
can use an action filter, for instance, to modify the view data that a controller action
returns.
Result filters contain logic that is executed before and after a view result is executed. For
example, you might want to modify a view result right before the view is rendered to the
browser.
Exception filters are the last type of filter to run. You can use an exception filter to handle
errors raised by either your controller actions or controller action results. You also can use
exception filters to log errors.
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 System.Web.Mvc.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 IAuthorizationFilter, IActionFilter,
IResultFilter, or ExceptionFilter interfaces.
The Base ActionFilterAttribute Class
In order to make it easier for you to implement a custom action filter, the ASP.NET MVC
framework includes a base ActionFilterAttribute class. This class implements both the
IActionFilter and IResultFilter interfaces and inherits from the FilterAttribute class.
The terminology here is not entirely consistent. Technically, a class that inherits from the
ActionFilterAttribute class is both an action filter and a result filter. However, in the loose
sense, the word action filter is used to refer to any type of filter in the ASP.NET MVC
framework.
The base ActionFilterAttribute class has the following methods that you can override:
• OnActionExecuting – This method is called before a controller action is executed.
• OnActionExecuted – This method is called after a controller action is executed.
• OnResultExecuting – This method is called before a controller action result is
executed.
• OnResultExecuted – This method is called after a controller action result is executed.
In the next section, we’ll see how you can implement each of these different methods.
Creating a Log Action Filter
In order to illustrate how you can build a custom action filter, we’ll create a custom action
filter that logs the stages of processing a controller action to the Visual Studio Output
window. Our LogActionFilter is contained in Listing 2.
Listing 2 – ActionFilters\LogActionFilter.cs
using System;
using System.Diagnostics;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1.ActionFilters
{
public class LogActionFilter : ActionFilterAttribute
{
public override void
OnActionExecuting(ActionExecutingContext filterContext)
{
Log("OnActionExecuting", filterContext.RouteData);
}
public override void OnActionExecuted(ActionExecutedContext
filterContext)
{
Log("OnActionExecuted", filterContext.RouteData);
}
public override void
OnResultExecuting(ResultExecutingContext filterContext)
{
Log("OnResultExecuting", filterContext.RouteData);
}
public override void OnResultExecuted(ResultExecutedContext
filterContext)
{
Log("OnResultExecuted", filterContext.RouteData);
}
private void Log(string methodName, RouteData routeData)
{
var controllerName = routeData.Values["controller"];
var actionName = routeData.Values["action"];
var message = String.Format("{0} controller:{1}
action:{2}", methodName, controllerName, actionName);
Debug.WriteLine(message, "Action Filter Log");
}
}
}
In Listing 2, the OnActionExecuting(), OnActionExecuted(), OnResultExecuting(), and
OnResultExecuted() methods all call the Log() method. The name of the method and the
current route data is passed to the Log() method. The Log() method writes a message to
the Visual Studio Output window (see Figure 2).
Figure 2 – Writing to the Visual Studio Output window
The Home controller in Listing 3 illustrates how you can apply the Log action filter to an
entire controller class. Whenever any of the actions exposed by the Home controller are
invoked – either the Index() method or the About() method – the stages of processing the
action are logged to the Visual Studio Output window.
Listing 3 – Controllers\HomeController.cs
using System.Web.Mvc;
using MvcApplication1.ActionFilters;
namespace MvcApplication1.Controllers
{
[LogActionFilter]
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult About()
{
return View();
}
}
}
Summary
In this tutorial, you were introduced to ASP.NET MVC action filters. You learned about the
four different types of filters: authorization filters, action filters, result filters, and exception
filters. You also learned about the base ActionFilterAttribute class.
Finally, you learned how to implement a simple action filter. We created a Log action filter
that logs the stages of processing a controller action to the Visual Studio Output window.













ASP.NET MVC provides a simple way to inject your piece of code or logic either before or after an action is executed. This is achieved by decorating the controllers or actions with ASP.NET MVC attributes or custom attributes. An attribute or custom attribute implements the ASP.NET MVC filters(filter interface) and can contain your piece of code or logic. You can make your own custom filters or attributes either by implementing ASP.NET MVC filter interface or by inheriting and overriding methods of ASP.NET MVC filter attribute class if available.
Typically, Filters are used to perform the following common functionalities in your ASP.NET MVC application.
  1. Custom Authentication
  2. Custom Authorization(User based or Role based)
  3. Error handling or logging
  4. User Activity Logging
  5. Data Caching
  6. Data Compression

Types of Filters

The ASP.NET MVC framework provides five types of filters.
  1. Authentication filters (New in ASP.NET MVC5)
  2. Authorization filters
  3. Action filters
  4. Result filters
  5. Exception filters

Authentication Filters

This filter is introduced with ASP.NET MVC5. The IAuthenticationFilter interface is used to create CustomAuthentication filter. The definition of this interface is given below-
  1. public interface IAuthenticationFilter
  2. {
  3. void OnAuthentication(AuthenticationContext filterContext);
  4.  
  5. void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext);
  6. }
You can create your CustomAuthentication filter attribute by implementing IAuthenticationFilter as shown below-
  1. public class CustomAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter
  2. {
  3. public void OnAuthentication(AuthenticationContext filterContext)
  4. {
  5. //Logic for authenticating a user
  6. }
  7. //Runs after the OnAuthentication method
  8. public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
  9. {
  10. //TODO: Additional tasks on the request
  11. }
  12. }

Authorization Filters

The ASP.NET MVC Authorize filter attribute implements the IAuthorizationFilter interface. The definition of this interface is given below-
  1. public interface IAuthorizationFilter
  2. {
  3. void OnAuthorization(AuthorizationContext filterContext);
  4. }
The AuthorizeAttribute class provides the following methods to override in the CustomAuthorize attribute class.
  1. public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter
  2. {
  3. protected virtual bool AuthorizeCore(HttpContextBase httpContext);
  4. protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext);
  5. public virtual void OnAuthorization(AuthorizationContext filterContext);
  6. protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext);
  7. }
In this way you can make your CustomAuthorize filter attribute either by implementing IAuthorizationFilter interface or by inheriting and overriding above methods of AuthorizeAttribute class.

Action Filters

Action filters are executed before or after an action is executed. The IActionFilter interface is used to create an Action Filter which provides two methods OnActionExecuting and OnActionExecuted which will be executed before or after an action is executed respectively.
  1. public interface IActionFilter
  2. {
  3. void OnActionExecuting(ActionExecutingContext filterContext);
  4. void OnActionExecuted(ActionExecutedContext filterContext);
  5. }

Result Filters

Result filters are executed before or after generating the result for an action. The Action Result type can be ViewResult, PartialViewResult, RedirectToRouteResult, RedirectResult, ContentResult, JsonResult, FileResult and EmptyResult which derives from the ActionResult class. Result filters are called after the Action filters. The IResultFilter interface is used to create an Result Filter which provides two methods OnResultExecuting and OnResultExecuted which will be executed before or after generating the result for an action respectively.
  1. public interface IResultFilter
  2. {
  3. void OnResultExecuted(ResultExecutedContext filterContext);
  4. void OnResultExecuting(ResultExecutingContext filterContext);
  5. }

Exception Filters

Exception filters are executed when exception occurs during the actions execution or filters execution. The IExceptionFilter interface is used to create an Exception Filter which provides OnException method which will be executed when exception occurs during the actions execution or filters execution.
  1. public interface IExceptionFilter
  2. {
  3. void OnException(ExceptionContext filterContext);
  4. }
ASP.NET MVC HandleErrorAttribute filter is an Exception filter which implements IExceptionFilter. When HandleErrorAttribute filter receives the exception it returns an Error view located in the Views/Shared folder of your ASP.NET MVC application.

Order of Filter Execution

All ASP.NET MVC filter are executed in an order. The correct order of execution is given below:
  1. Authentication filters
  2. Authorization filters
  3. Action filters
  4. Result filters

Configuring Filters

You can configure your own custom filter into your application at following three levels:
  1. Global level

    By registering your filter into Application_Start event of Global.asax.cs file with the help of FilterConfig class.
    1. protected void Application_Start()
    2. {
    3. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    4. }
  2. Controller level

    By putting your filter on the top of the controller name as shown below-
    1. [Authorize(Roles="Admin")]
    2. public class AdminController : Controller
    3. {
    4. //
    5. }
  3. Action level

    By putting your filter on the top of the action name as shown below-
    1. public class UserController : Controller
    2. {
    3. [Authorize(Users="User1,User2")]
    4. public ActionResult LinkLogin(string provider)
    5. {
    6. // TODO:
    7. return View();
    8. }
    9. }
    http://www.codeproject.com/Articles/577776/Filters-and-Attributes-in-ASPNET-MVC
  4. http://www.codeproject.com/Articles/650240/A-Simple-Action-Filter-Overview

No comments:

Post a Comment