如何拦截MVC应用程序中的所有控制器调用?

时间:2012-02-21 19:24:11

标签: asp.net-mvc-3 debugging logging

是否有一种快速方法可以拦截MVC-3中的所有控制器调用?

为了进行日志记录和测试,我想构建一个工具,它可以拦截所有控制器调用,并在什么时间记录调用哪个控制器,以及哪条消息。

4 个答案:

答案 0 :(得分:22)

我不记得我从哪里得到这个,但是我一直在寻找类似的东西,发现一篇文章或某个包含这个日志过滤器的东西:

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

要使用它,只需将其添加到global.asax中的全局过滤器:

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

我现在看看是否可以找到来源。

编辑:找到它。它来自this question

答案 1 :(得分:5)

根据站点的大小,您可以在框架的Controller类和主控制器之间的层次结构中创建一个类。

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

然后其余的控制器可以从此继承,例如

public class HomeController : MyBaseController {
    // action methods...
}

答案 2 :(得分:2)

您可以使用自己的控制器工厂并注册它: 从:(网上很多例子 - 在你想要的地方插入记录)

改编自: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
    }
}

别忘了在global.asax.cs中注册它

ControllerBuilder.Current.SetControllerFactory(
                typeof(YourControllerFactory));

答案 3 :(得分:1)

有一个由Phil Haack开发的路由调试器

ASP.Net Routing Debugger