Tallan's Technology Blog

Tallan's Top Technologists Share Their Thoughts on Today's Technology Challenges

Global Action Filters in ASP.NET MVC 3

Action Filters are a great way to handle cross-cutting concerns in ASP.NET MVC such as Logging, ExceptionHandling, etc.  In previous versions of MVC3, action filters have to be explicitly added to each controller. 

MVC3 adds the concept of Global Action Filters which allow you to apply action filters globally without the need for explicit declaration.  In this example, we’ll demonstrate how to add a debug action filter attribute that shows debug information for each view using Global Action Filters.

DebugInfoAttribute.cs

Code Snippet
  1. /// <summary>
  2.     /// Displays the elapsed time and environment for each executed action in the HTTP Response Stream.
  3.     /// </summary>
  4.     public class DebugInfoAttribute : ActionFilterAttribute
  5.     {
  6.         readonly Stopwatch _startWatch = new Stopwatch();
  7.         private static string _outputFormat = "<h4>Debug Environment Info</h4><div class=\"debuginfo\"><table><tr><td>Web Server:</td><td>{0}</td></tr><tr><td>Browser:</td><td>{1}</td></tr><tr><td>Controller</td><td>{3}</td></tr><tr><td>Action:</td><td>{4}</td></tr><tr><td>Execution Time(ms):</td><td>{5}</td></tr></table></div>";
  8.         public override void OnActionExecuting(ActionExecutingContext filterContext)
  9.         {
  10.             _startWatch.Start();
  11.         }
  12.  
  13.         public override void OnResultExecuted(ResultExecutedContext filterContext)
  14.         {
  15.             _startWatch.Stop();
  16.             var browser = filterContext.HttpContext.Request.Browser;
  17.             filterContext.HttpContext.Response.Write(string.Format(_outputFormat,
  18.                                                                    HttpContext.Current.Request.ServerVariables[
  19.                                                                        "SERVER_NAME"],
  20.                                                                    String.Format("{0} ({1})",browser.Browser,browser.Version),
  21.                                                                        filterContext.RouteData.Values["controller"],???????????????
  22.                                                                        filterContext.RouteData.Values["action"],
  23.                                                                        _startWatch.ElapsedMilliseconds));
  24.  
  25.         }
  26.     }

This action filter uses the StopWatch object to clock how long the action took to execute, and displays that information in a view.

It’s applied normally by adding the “DebugInfo” attribute to the top of a controller class, as below.

Code Snippet
  1. [DebugInfo]
  2.     public class HomeController : Controller

 

This results in the output seen below on our views:

image

If we click the “LogOn” link on our default application, we won’t see this information as we haven’t applied this filter to the “Account” controller.  Lets see how we can set an action filter to display gloablly.

Registering Global Action Filters

MVC3 adds a new function into our Global.asax called Register Global Filters.  To apply a filter globally, simply add a new line specifying your action filter as below.

Code Snippet
  1. public static void RegisterGlobalFilters(GlobalFilterCollection filters)
  2.         {
  3.             filters.Add(new HandleErrorAttribute());
  4.             filters.Add(new DebugInfoAttribute());
  5.         }

Now, when we click on the “Log On” link, we can see the DebugInfo filter has been automatically applied to the Account controller.

image

5 Comments. Leave new

This would have been more useful to me if you had done the logging to a database like SQL Server

Como puedo agregar politicas o roles a usuarios en MVC 3. Necesito crear politicas de acceso a modulos para un proyecto que estoy realizando en ASP.NET MVC
Gracias,

[…] use the attribute on each action and by default it will apply to all Controller Actions.Here is an article by Michael Gerety on how to create Global Action Filters.This is simple enough, but here is the source code, Please […]

I think it should be – _startWatch.Restart();

Good explanation. Thanks.
After publishing the result, I did reset the stopwatch. It’s now showing individual time elapsed.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>