在 Asp.net MVC 和 Web API 中实施审计跟踪的干净方法是什么
What is the clean way to Implement Audit Trail in Asp.net MVC and Web API
我正在寻找一种更简洁的方法来将审计跟踪功能添加到现有的 asp.net MVC 和 Web Api 项目中,该项目包含数百个 Controller
和 ApiController
.
审计跟踪日志如下所示。基本上我只想在这个函数中记录 In what time who did what
。
UserID
ActionTime
Controller
Action
我错过了什么吗?如果有 。请纠正我。谢谢。
目前我发现有一些方法可以做到。
实现一个ActionFilterAttribute
并在OnActionExecuting
中编写自己的日志函数,然后用这个属性装饰所有的动作。
为所有存在的控制器实现一个基础Controller
,如BaseController
。并在 OnActionExecuting
中写入日志。然后把所有的controller改成继承自BaseController
。 (如有不妥请指正谢谢)
为ApiController
。实现一个 DelegatingHandler
来实现它。
对于 1 和 2。我需要更改所有现有代码才能实现。比如更改基础 class 或使用新属性进行装饰。考虑到我的情况,这将是一项艰苦的工作。因为需要更改成千上万的 class 或方法。我认为这有点冗长。所以我想知道是否有一些像 3 for ApiController 那样干净的方法来实现它。谢谢。
您使用的是 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);
}
}
如果您打算使用它,请查看 the examples on this site。我确信有一种方法可以将它用于 Web API 和 MVC 控制器。
我发现使用全局操作过滤器是处理 cross-cutting/aspect-oriented 此类问题的最佳方式。
请注意,此代码未经测试。
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));
}
}
然后在您的应用程序启动管道的某处,全局注册过滤器:
GlobalConfiguration.Configuration.Filters.Add(new AuditFilter());
我正在寻找一种更简洁的方法来将审计跟踪功能添加到现有的 asp.net MVC 和 Web Api 项目中,该项目包含数百个 Controller
和 ApiController
.
审计跟踪日志如下所示。基本上我只想在这个函数中记录 In what time who did what
。
UserID
ActionTime
Controller
Action
我错过了什么吗?如果有 。请纠正我。谢谢。
目前我发现有一些方法可以做到。
实现一个
ActionFilterAttribute
并在OnActionExecuting
中编写自己的日志函数,然后用这个属性装饰所有的动作。为所有存在的控制器实现一个基础
Controller
,如BaseController
。并在OnActionExecuting
中写入日志。然后把所有的controller改成继承自BaseController
。 (如有不妥请指正谢谢)为
ApiController
。实现一个DelegatingHandler
来实现它。
对于 1 和 2。我需要更改所有现有代码才能实现。比如更改基础 class 或使用新属性进行装饰。考虑到我的情况,这将是一项艰苦的工作。因为需要更改成千上万的 class 或方法。我认为这有点冗长。所以我想知道是否有一些像 3 for ApiController 那样干净的方法来实现它。谢谢。
您使用的是 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);
}
}
如果您打算使用它,请查看 the examples on this site。我确信有一种方法可以将它用于 Web API 和 MVC 控制器。
我发现使用全局操作过滤器是处理 cross-cutting/aspect-oriented 此类问题的最佳方式。
请注意,此代码未经测试。
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));
}
}
然后在您的应用程序启动管道的某处,全局注册过滤器:
GlobalConfiguration.Configuration.Filters.Add(new AuditFilter());