【问题标题】:What is the clean way to Implement Audit Trail in Asp.net MVC and Web API在 Asp.net MVC 和 Web API 中实现审计跟踪的干净方法是什么
【发布时间】:2015-12-22 18:32:46
【问题描述】:

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

审计跟踪日志如下所示。基本上我只想在这个函数中记录In what time who did what

UserID

ActionTime

Controller 

Action

我错过了什么?如果有 。请纠正我。谢谢。

目前我发现有一些方法可以做到。

  1. 实现一个ActionFilterAttribute,并在OnActionExecuting中编写我自己的日志函数,然后用这个属性装饰所有的动作。

  2. 为所有现有控制器实现一个基本的Controller,如BaseController。并在OnActionExecuting 中写入日志。然后将所有控制器更改为从BaseController 继承。 (如有错误请指正。谢谢。)

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

对于 1 和 2。我需要更改所有现有代码才能完成。比如改变基类或用新属性装饰。考虑到我的情况,这将是一项艰苦的工作。因为成千上万的类或方法需要改变。我认为这有点冗长。所以我想知道 ApiController 是否有像 3 这样的干净方法来实现它。谢谢。

【问题讨论】:

  • 我认为您可以使用ActionFiltersMessageHandlers 的组合来做到这一点。请参阅 github 上的 stackoverflow.com/a/12300537/325521codeproject.com/Articles/581908/… 源代码 => github.com/Rionmonster/Advanced-Auditing
  • MVC 控制器中有没有类似 DelegatingHandler 的东西?所以我不需要更改现有代码。对不起。我是懒人。。谢谢。
  • 我知道你提到的方法是很好的解决方法。但我只是想找出一种更好或懒惰的方法。谢谢。
  • 这两个库实现了动作过滤器,为 NET Core 和 NET 4.5 的 WebAPI 和 MVC 生成审计跟踪。你可以看看Audit.MVCAudit.WebApi上的代码
  • 这是一个非常好的库。他们工作得很好。感谢您的帮助。

标签: c# asp.net-mvc asp.net-mvc-5 audit


【解决方案1】:

我发现使用全局操作过滤器是处理诸如此类的横切/面向方面问题的最佳方式。

请注意,此代码未经测试。

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());

【讨论】:

  • 这是MVC中最简单的拦截方式。谢谢你。
  • 其实这个是针对Web API的。您必须为 MVC 创建一个单独的,看起来基本相同,除了您将从 RouteData 获取控制器和操作名称并使用 GlobalFilters.Filters.Add(...) 注册过滤器。
  • 我了解此解决方案将有助于记录请求的一部分。假设我想扩展它以在执行实际控制器方法后捕获成功/失败并记录相同的内容 - 对此有何建议?
【解决方案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);
}
}

如果您打算使用它,请查看the examples on this site。我确信有一种方法可以将它用于 Web API 和 MVC 控制器。

【讨论】:

  • +1 是的。这是一个好主意。我的项目中已经有Unity。但是......所有控制器都不是在运行时从工厂创建的。恐怕拦截器无法正常工作......我需要做一些研究。谢谢。
  • 我担心另一个问题是使用 Unity 拦截会丢失 MVC 控制器和 WebApiController 的上下文。我的意思是检索路由数据等信息并不容易。请求和响应等。对吗?
  • 这对您有帮助吗? stackoverflow.com/questions/19794438/…
  • em....需要更多时间阅读。但这应该是审核 MVC 和 WebApi 的有效方法。谢谢。
猜你喜欢
  • 2015-12-14
  • 2010-10-16
  • 2016-09-15
  • 2011-08-27
  • 1970-01-01
  • 2022-01-03
  • 2010-09-24
  • 1970-01-01
  • 2010-09-13
相关资源
最近更新 更多