Exercise 2: Managing Multiple Action Filters
In this exercise you will add a second Custom Action Filter to the StoreController class and define the specific order in which both filters will be executed. Then you will update the code to register the filter Globally.
There are different options to take into account when defining the Filters’ execution order. For example, the Order property and the Filters’ scope:
You can define a Scope for each of the Filters, for example, you could scope all the Action Filters to run within theController Scope, and all Authorization Filters to run in Global scope. The scopes have a defined execution order.
Additionally, each action filter has an Order property which is used to determine the execution order in the scope of the filter.
For more information about Custom Action Filters execution order, please visit this MSDN article: (http://msdn.microsoft.com/en-us/library/dd381609%28v=vs.98%29.aspx).
Task 1: Creating a new Custom Action Filter
In this task, you will create a new Custom Action Filter to inject into the StoreController class, learning how to manage the execution order of the filters.
- Open the Begin solution located at \Source\Ex02-ManagingMultipleActionFilters\Begin folder. Otherwise, you might continue using the End solution obtained by completing the previous exercise.
- If you opened the provided Begin solution, you will need to download some missing NuGet packages before continue. To do this, click the Project menu and select Manage NuGet Packages.
- In the Manage NuGet Packages dialog, click Restore in order to download missing packages.
- Finally, build the solution by clicking Build | Build Solution.
Note: One of the advantages of using NuGet is that you don’t have to ship all the libraries in your project, reducing the project size. With NuGet Power Tools, by specifying the package versions in the Packages.config file, you will be able to download all the required libraries the first time you run the project. This is why you will have to run these steps after you open an existing solution from this lab.
For more information, see this article: http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.
- Add a new C# class into the Filters folder and name it MyNewCustomActionFilter.cs
- Open MyNewCustomActionFilter.cs and add a reference to System.Web.Mvc and theMvcMusicStore.Models namespace:(Code Snippet – ASP.NET MVC 4 Custom Action Filters – Ex2-MyNewCustomActionFilterNamespaces)C#
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MvcMusicStore.Models;
- Replace the default class declaration with the following code.(Code Snippet – ASP.NET MVC 4 Custom Action Filters – Ex2-MyNewCustomActionFilterClass)C#
public class MyNewCustomActionFilter : ActionFilterAttribute, IActionFilter { void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext) { // TODO: Add your acction filter's tasks here // Log Action Filter Call MusicStoreEntities storeDB = new MusicStoreEntities(); ActionLog log = new ActionLog() { Controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, Action = filterContext.ActionDescriptor.ActionName + " (Logged By: MyNewCustomActionFilter)", IP = filterContext.HttpContext.Request.UserHostAddress, DateTime = filterContext.HttpContext.Timestamp }; storeDB.ActionLogs.Add(log); storeDB.SaveChanges(); this.OnActionExecuting(filterContext); } }
Note: This Custom Action Filter is almost the same than the one you created in the previous exercise. The main difference is that it has the “Logged By” attribute updated with this new class’ name to identify wich filter registered the log.
Task 2: Injecting a new Code Interceptor
In this task, you will add a new custom filter into the StoreController Class and run the solution to verify how both filters work together.
- Open the StoreController class located at MvcMusicStore\Controllers and inject the new custom filterMyNewCustomActionFilter into StoreController class like is shown in the following code.C#
[MyNewCustomActionFilter] [CustomActionFilter] public class StoreController : Controller { ... }
- Now, run the application in order to see how these two Custom Action Filters work. To do this, press F5 and wait until the application starts.
- Browse to /ActionLog to see log view initial state.
- Click one of the Genres from the menu and perform some actions there, like browsing an available album.
- Check that this time; your visits were tracked twice: once for each of the Custom Action Filters you added in the StorageController class.
- Close the browser.
Task 3: Managing Filter Ordering
In this task, you will learn how to manage the filters’ execution order by using the Order propery.
- Open the StoreController class located at MvcMusicStore\Controllers and specify the Order property in both filters like shown below.C#
[MyNewCustomActionFilter(Order = 2)] [CustomActionFilter(Order = 1)] public class StoreController : Controller { ... }
- Now, verify how the filters are executed depending on its Order property’s value. You will find that the filter with the smallest Order value (CustomActionFilter) is the first one that is executed. Press F5 and wait until the application starts.
- Browse to /ActionLog to see log view initial state.
- Click one of the Genres from the menu and perform some actions there, like browsing an available album.
- Check that this time, your visits were tracked ordered by the filters’ Order value: CustomActionFilter logs’ first.
- Now, you will update the Filters’ order value and verify how the logging order changes. In theStoreController class, update the Filters’ Order value like shown below.C#
[MyNewCustomActionFilter(Order = 1)] [CustomActionFilter(Order = 2)] public class StoreController : Controller { ... }
- Run the application again by pressing F5.
- Click one of the Genres from the menu and perform some actions there, like browsing an available album.
- Check that this time, the logs created by MyNewCustomActionFilter filter appears first.
Task 4: Registering Filters Globally
In this task, you will update the solution to register the new filter (MyNewCustomActionFilter) as a global filter. By doing this, it will be triggered by all the actions perfomed in the application and not only in the StoreController ones as in the previous task.
- In StoreController class, remove [MyNewCustomActionFilter] attribute and the order property from[CustomActionFilter]. It should look like the following:C#
[CustomActionFilter] public class StoreController : Controller { ... }
- Open Global.asax file and locate the Application_Start method. Notice that each thime the application starts it is registering the global filters by calling RegisterGlobalFilters method within FilterConfig class.
- Open FilterConfig.cs file within App_Start folder.
- Add a reference to using System.Web.Mvc; using MvcMusicStore.Filters; namespace.C#
using System.Web.Mvc; using MvcMusicStore.Filters;
- Update RegisterGlobalFilters method adding your custom filter. To do this, add the highlighted code:C#
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); filters.Add(new MyNewCustomActionFilter()); }
- Run the application by pressing F5.
- Click one of the Genres from the menu and perform some actions there, like browsing an available album.
- Check that now [MyNewCustomActionFilter] is being injected in HomeController and ActionLogController too.
source : http://www.asp.net/mvc/tutorials/hands-on-labs/aspnet-mvc-4-custom-action-filters