In this exercise you will learn how to create a custom action log filter by using MVC3 Filter Providers. For that purpose you will apply a logging filter to the MusicStore site that will record all the activities in the selected controllers.
The filter will extend ActionFilterAttributeClass and override OnActionExecuting method to catch each request and then perform the logging actions. The context information about HTTP requests, executing methods, results and parameters will be provided by MVC ActionExecutingContext class.
About MVC Music Store Application logging feature
This Music Store solution has a new data model table for site logging, ActionLog, with the following fields: Name of the controller that received a request, Called action, Client IP and Time stamp.

Figure 1
Data model. ActionLog table.
The solution provides an MVC View for the Action log that can be found at MvcMusicStores/Views/ActionLog:

Figure 1
Action Log view.
With this given structure, all the work will be focused on interrupting controller’s request and performing the logging by using custom filtering.
Task 1 – Creating a custom filter to catch a controller’s request
In this task you will create a custom filter attribute class that will contain the logging logic. For that purpose you will extend MVC ActionFilterAttribute Class and implement the interface IActionFilter.
Note: |
|---|
| ActionFilterAttribute is the base class for all the attribute filters. It provides the following methods to execute a specific logic after and before controller action’s execution: - OnActionExecuting(ActionExecutedContext filterContext) Just before the action method is called - OnActionExecuted(ActionExecutingContext filterContext): After the action method is called and before the result is executed (before view render). - OnResultExecuting(ResultExecutingContext filterContext): Just before the result is executed (before view render). - OnResultExecuted(ResultExecutedContext filterContext): After the result is executed (after the view is rendered). By overriding any of these methods into a derived class, you can execute your own filtering code. |
- Open the begin solution MvcMusicStore.sln at Source\Ex01-Logging Actions\Begin
- Create a new folder Filters at project root, which will include all the custom filters.
- Add a new C# class into the Filters folder and rename it to ActionLogFilterAttribute.cs
- Open ActionLogFilterAttribute.cs and add a reference to System.Web.Mvc and the MvcMusicStore.Models namespace:
C#
Copy Code
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MvcMusicStore.Models;
- Inherit the ActionLogFilterAttribute class from ActionFilterAttribute and then make ActionLogFilterAttribute class implement IActionFilter interface.
- Make ActionLogFilterAttribute class override the method OnActionExecuting, where you will write the logging code. After that, your class should look like the following:
(Code Snippet – ASP.NET MVC 3 Custom Action Filters – Ex1 Logging Actions - CSharp)
C#
Copy Code
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MvcMusicStore.Models; namespace MvcMusicStore.Filters { public class ActionLogFilterAttribute : ActionFilterAttribute, IActionFilter { public override void OnActionExecuting(ActionExecutingContext filterContext) { MusicStoreEntities storeDB = new MusicStoreEntities(); ActionLog log = new ActionLog() { Controller = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName, Action = filterContext.ActionDescriptor.ActionName, IP = filterContext.HttpContext.Request.UserHostAddress, DateTime = filterContext.HttpContext.Timestamp }; storeDB.AddToActionLogs(log); storeDB.SaveChanges(); base.OnActionExecuting(filterContext); } } }
| C# | Copy Code
|
|---|---|
...
namespace MvcMusicStore.Filters
{
public class ActionLogFilterAttribute : ActionFilterAttribute, IActionFilter
{
...
| |
Note: |
|---|
| Note: OnActionExecuting method is using Entity Framework to add a new ActionLog register. It creates and fills a new entity instance with the context information from filterContext. You could read more about ControllerContext class at msdn. |
Task 2 – Injecting a code interceptor into the Store Controller class
In this task you will add the custom filter by injecting it to all controller classes and controller actions that will be logged. For the purpose of this exercise, the Store Controller class will have a log.
The method OnActionExecuting from ActionLogFilterAttribute custom filter runs when an injected element is called.
It is also possible to intercept a specific controller method.
- Open the StoreController at MvcMusicStore\Controllers and add a reference to the Filters namespace:
C#
Copy Code
… using MvcMusicStore.ViewModels; using MvcMusicStore.Models; using MvcMusicStore.Filters; namespace MvcMusicStore.Controllers { …- Inject the custom filter ActionLogFilter into StoreController class.
C#
Copy Code
… using MvcMusicStore.ViewModels; using MvcMusicStore.Models; using MvcMusicStore.Filters; namespace MvcMusicStore.Controllers { [ActionLogFilter] public class StoreController : Controller { MusicStoreEntities storeDB = new MusicStoreEntities(); // // GET: /Store/ public ActionResult Index() { // Create list of genres …
Note: |
|---|
| When a filter is injected into a controller class, all its actions are also injected. If you would like to apply the filter only for a set of actions, you would have to inject [ActionLogFilter] to each one of them: [ActionLogFilter] public ActionResult Index() { … } … [ActionLogFilter] public ActionResult Browse(string genre) { … } |
Task 3 – Running the application
In this task you will test that the logging filter is working. You will start the application and visit the store, and then you will check logged activities.
- Press F5 to run the application.
- Browse to /ActionLog to see log view initial state:

Figure 2
Log tracker status before page activity.- Browse to /Store and perform some actions there, like browsing an album detail.
- Browse to /ActionLog and if the log is empty press F5 to refresh the page. Check that your visits were tracked:

Figure 3
Action log with activity logged
Note: