在Asp.net MVC和Web API中实现Audit Trail的简洁方法是什么?

Joe*_*ang 5 c# asp.net-mvc audit asp.net-mvc-5

我正在寻找一种更简洁的方法来将审计跟踪功能添加到现有的asp.net MVC和Web Api项目中,该项目包含数百个ControllerApiController.

审计跟踪日志如下所示.基本上我只想登录In what time who did what这个功能.

UserID

ActionTime

Controller 

Action
Run Code Online (Sandbox Code Playgroud)

我错过了什么?如果有 .请指正.谢谢.

目前我发现有一些方法可以做到这一点.

  1. 在中实现ActionFilterAttribute并编写自己的日志函数OnActionExecuting,然后使用此属性修饰所有操作.

  2. ControllerBaseController所有存在的控制器一样实现基础.并写入登录OnActionExecuting.然后将所有控制器更改为继承BaseController.(如果是错的.请纠正我.谢谢.)

  3. 对于ApiController.实现一个DelegatingHandler来实现它.

对于1和2.我需要更改所有存在的代码来实现它.比如改变基类或用新属性装饰.考虑到我的情况,这将是一项艰苦的工作.因为需要改变数以千计的类或方法.我觉得它有点冗长.所以我想知道是否有一些像ApiController这样的干净方式来制作它.谢谢.

Ron*_*ers 11

我发现使用全局动作过滤器是处理横切/面向方面问题的最佳方法.

请注意,此代码未经过测试.

public class AuditFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var userName = HttpContext.Current.User.Identity.Name;
        var time = DateTime.Now.ToString(CultureInfo.InvariantCulture);
        var controllerName = actionContext.ControllerContext.ControllerDescriptor.ControllerName;
        var actionName = actionContext.ActionDescriptor.ActionName

        Logger.Log(string.Format("user: {0}, date: {1}, controller {2}, action {3}", userName, time, controllerName, actionName));
    }
}
Run Code Online (Sandbox Code Playgroud)

在应用程序启动管道的某处,全局注册过滤器:

GlobalConfiguration.Configuration.Filters.Add(new AuditFilter());
Run Code Online (Sandbox Code Playgroud)


Muk*_*kus 2

您使用 DI 容器吗?如果您是或想要使用 DI 容器,它可能会拦截对控制器的所有请求。这样,您就不必更改数百个控制器中的代码,尽管更改很简单。

这里是温莎城堡 DI。

public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IKernel _kernel;

public WindsorControllerFactory(IKernel kernel)
{
    _kernel = kernel;
}

public override void ReleaseController(IController controller)
{
    _kernel.ReleaseComponent(controller);
}

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
    if (controllerType == null)
    {
        throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
    }

    return (IController)_kernel.Resolve(controllerType);
}
}
Run Code Online (Sandbox Code Playgroud)

如果您打算使用它,请查看该网站上的示例。我确信有一种方法可以将它用于 Web API 和 MVC 控制器。