16

Is there a quick method for intercepting all controller calls in MVC-3?

For logging and testing purposes, I'd like to build a tool that can intercept all controller calls, and log which controller was called, with which message, at what time.

blueberryfields
  • 45,910
  • 28
  • 89
  • 168

4 Answers4

24

I can't remember where I got this from, but I was looking around for something similar a while back and found an article or something somewhere that contained this logging filter:

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");
    }
}

To use it, just add it to the global filters in global.asax:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new LogActionFilter());
}

I'll have a look now to see if I can find the source.

Edit: Found it. It was from this question.

Community
  • 1
  • 1
John H
  • 14,422
  • 4
  • 41
  • 74
  • This answer is directly from Microsoft Docs. https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/understanding-action-filters-cs – Hermes Trismegistus Oct 30 '18 at 15:28
5

Depending on how big the site is already, you could create a class in the hierarchy between the framework's Controller class and your main controllers.

Something like

public class MyBaseController : Controller {
    protected override void OnActionExecuting(ActionExecutingContext filterContext) {
        // your logging stuff here
        base.OnActionExecuting(filtercontext);
    }
}

Then the rest of your controllers can inherit from this, e.g.

public class HomeController : MyBaseController {
    // action methods...
}
Dave
  • 1,338
  • 12
  • 17
2

You can use your own controller factory and register it as well: From: (many example on the net - insert logging where you want)

adapted from: http://www.keyvan.ms/custom-controller-factory-in-asp-net-mvc

using System;
using System.Configuration;
using System.Web.Mvc;
using System.Web.Routing;

namespace IControllerFactorySample.ControllerFactories
{
    public class YourControllerFactory : IControllerFactory
    {
        #region IControllerFactory Members

        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (string.IsNullOrEmpty(controllerName))
                throw new ArgumentNullException("controllerName");

            IController controller = Activator.CreateInstance(Type.GetType(controllerName)) as IController;

            return controller;
        }

        public void ReleaseController(IController controller)
        {
            if (controller is IDisposable)
                (controller as IDisposable).Dispose();
            else
                controller = null;
        }

        #endregion
    }
}

dont forget to register it in global.asax.cs

ControllerBuilder.Current.SetControllerFactory(
                typeof(YourControllerFactory));
Adam Tuliper
  • 29,982
  • 4
  • 53
  • 71
  • PS you can also use some method of aspect oriented programming (AOP) and inject via postsharp or spring.net has an engine you can use to intercept calls as well (which goes beyond just the controller but you can set a regex in the config file to apply I believe to classes with a name 'Controller' on them. – Adam Tuliper May 22 '12 at 14:17
1

there is a routing debugger developed by Phil Haack

ASP.Net Routing Debugger

Rafay
  • 30,950
  • 5
  • 68
  • 101