Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

ASP.NET MVC 3: Using global action filters to find out running time of controller actions

Lately I blogged about global action filters in ASP.NET MVC 3. Yesterday I found cool article from Nick Berardi’s Coder Journal where he introduces how to use action filters to measure running time of ASP.NET MVC controllers. And here is my experiment – how to use global action filters to find out how long controller actions are running. You just need couple of lines of code.

Source code

You can find source code of this example from Visual Studio 2010 experiments repository at GitHub.

Source code @ GitHub Source code repository
GitHub

Example is located in Experiments.AspNetMvc3NewFeatures.GlobalActionFilters project.

StopwatcherAttribute class by Nick Berardi

To take time Nick uses StopwatchAttribute class that you can find from his GitHub repository. I paste this class also here so you can take a look at it without leaving this page. I made some modifications so you can use this class also with ASP.NET development web server.


public class StopwatchAttribute : ActionFilterAttribute
{
    private readonly Stopwatch _stopwatch;
 
    public StopwatchAttribute()
    {
        _stopwatch = new Stopwatch();
    }
 
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _stopwatch.Start();
    }
 
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        _stopwatch.Stop();
 
        var httpContext = filterContext.HttpContext;
        var response = httpContext.Response;
        var elapsed = _stopwatch.Elapsed.ToString();
 
        // Works for Cassini and IIS
        //response.Write(string.Format("<!-- X-Stopwatch: {0} -->", elapsed));  
 
        // Works for IIS
        response.AddHeader("X-Stopwatch", elapsed);
    }
}

Now let’s take default controller that is created when you create a new ASP.NET MVC web application.


public class HomeController : Controller
{
    public ActionResult Index()
    {
        ViewModel.Message = "Welcome to ASP.NET MVC!";
 
        return View();
    }
 
    public ActionResult About()
    {
        return View();
    }
}

We will add nothing to this code by ourselves. We leave it like it is. One thing we have to do is we have to modify our application class in Global.asax.cs.


protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
 
    GlobalFilters.Filters.Add(new StopwatchAttribute());
 
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

Okay, now it’s the moment of truth. Let’s see what ASP.NET MVC outputs when we request default page and About page. For both pages you should see something like this in page source.

Output of StopwatchAttribute

If you have controller actions that output something other than HTML you cannot write output of StopwatchAttribute class to response – use headers instead of response body.

Conclusion

Global action filters provided by ASP.NET MVC 3 are powerful tools. When working on IIS we can easily make our requests to be easily measured using StopwatchAttribute class when we register it as a global action filter and let it write it’s output to response headers. Tools like Firebug and Fiddler2 allow you to monitor HTTP traffic easily and it is not hard to read headers if you have some of these tools.

Comments

Bohdan said:

What is RegisterGlobalFilters() ???

# August 17, 2011 1:27 PM

jacerhea said:

This works for ASP.NET MVC 1 and 2, but not 3.  The filters are constructed once in MVC 3.  So a member variable will not work.  See Nick's updated code...

github.com/.../StopwatchAttribute.cs

# August 22, 2012 12:36 PM