asp.net-mvc – 如何拦截所有的ASP.NET WebApi控制器操作方法调用与Ninject拦截进行日志记录?

前端之家收集整理的这篇文章主要介绍了asp.net-mvc – 如何拦截所有的ASP.NET WebApi控制器操作方法调用与Ninject拦截进行日志记录?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我们公司有必要记录某些事情,每次我们的ASP.NET WebApi控制器的一个动作方法调用。由于我们现在使用Ninject作为DI,所以我们也希望将其用于此目的。这是我迄今为止所尝试过的。

我有Ninject,Ninject.Extensions.Interception和Ninject.Extensions.Interception.DynamicProxy通过NuGet安装,我有以下模块

public class InterceptAllModule : InterceptionModule
{
    public override void Load()
    {
        Kernel.Intercept(p => p.Request.Service.Name.EndsWith("Controller")).With(new TimingInterceptor());
    }
}

TimingInterceptor在哪里

public class TimingInterceptor : SimpleInterceptor
{
    readonly Stopwatch _stopwatch = new Stopwatch();
    protected override void BeforeInvoke(IInvocation invocation)
    {
        _stopwatch.Start();
    }

    protected override void AfterInvoke(IInvocation invocation)
    {
        _stopwatch.Stop();
        string message = string.Format("[Execution of {0} took {1}.]",invocation.Request.Method,_stopwatch.Elapsed);
        Log.Info(message + "\n");
        _stopwatch.Reset();
    }
}

现在,当我尝试用ninject内核挂接模块,并运行我的网站

var kernel = new StandardKernel(new InterceptAllModule());

但是,每当有一个呼叫进入一个动作方法时,它会发出一个错误

Cannot instantiate proxy of class: MyApiController.

有经验的人可以指出我在做错什么吗?谢谢。

解决方法

更新

所以使用你的代码和Remo的优点,需要动作方法是虚拟的,并放置一个空的默认构造函数(只是安抚动态代理,保持你的其他构造函数仍然)我已经有动作过滤器和拦截方法工作。

我会说,因为它的代码拦截ApiController上的潜在的不必要的方法,所以你可能还需要放置一些代码来过滤这些例子。执行同步和处理。

我唯一的其他观点就是表演。巨大的免责声明这些只是非常基本的测试(每次使用动作过滤器方法来记录统计信息),我邀请你做自己的(!)…但是使用DynamicProxy拦截器,我得到的时间约为4毫秒获得请求

[Execution of Get took 00:00:00.0046615.]
[Execution of Get took 00:00:00.0041988.]
[Execution of Get took 00:00:00.0039383.]

评论拦截代码并使用Action过滤器,我获得了毫秒级的性能

[Execution of Get took 00:00:00.0001146.]
[Execution of Get took 00:00:00.0001116.]
[Execution of Get took 00:00:00.0001364.]

这取决于你是否真的是一个问题或疑虑,但我以为我会指出这一点。

以前的回应

你使用ActionFilters吗?这是AOP对MVC动作的自然延伸点。

如果您对控制器上的实际操作以外的方法感兴趣,那么我会明白,但我以为我会发布一个建议。

灵感来自Are ActionFilterAttributes reused across threads? How does that work?Measure Time Invoking MVC 4 Controller Actions

更新以显示方法标记时计时器的排除。来自核心WebApi框架的灵感来自AllowAnonymousAttributeAuthorizeAttribute

在全局注册,以便所有操作由此进行监视:

GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());

然后:

public class TimingActionFilter : ActionFilterAttribute
{
    private const string Key = "__action_duration__";

    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (SkipLogging(actionContext))
        {
            return;
        }

        var stopWatch = new Stopwatch();
        actionContext.Request.Properties[Key] = stopWatch;
        stopWatch.Start();
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        if (!actionExecutedContext.Request.Properties.ContainsKey(Key))
        {
            return;
        }

        var stopWatch = actionExecutedContext.Request.Properties[Key] as Stopwatch;
        if(stopWatch != null)
        {
            stopWatch.Stop();
            var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;
            Debug.Print(string.Format("[Execution of {0} took {1}.]",actionName,stopWatch.Elapsed));
        }

    }

    private static bool SkipLogging(HttpActionContext actionContext)
    {
        return actionContext.ActionDescriptor.GetCustomAttributes<NoLogAttribute>().Any() ||
                actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<NoLogAttribute>().Any();
    }
}

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class,Inherited = true)]
public class NoLogAttribute : Attribute
{

}

现在可以使用以下方式排除全局过滤器:

public class ExampleController : ApiController
{
    // GET api/example
    [NoLog]
    public Example Get()
    {
       //
    }
}

猜你在找的asp.Net相关文章