Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 如何使用Ninject拦截来拦截所有ASP.NET WebApi控制器操作方法调用以进行日志记录?_Asp.net Mvc_Logging_Asp.net Web Api_Ninject_Ninject Interception - Fatal编程技术网

Asp.net mvc 如何使用Ninject拦截来拦截所有ASP.NET WebApi控制器操作方法调用以进行日志记录?

Asp.net mvc 如何使用Ninject拦截来拦截所有ASP.NET WebApi控制器操作方法调用以进行日志记录?,asp.net-mvc,logging,asp.net-web-api,ninject,ninject-interception,Asp.net Mvc,Logging,Asp.net Web Api,Ninject,Ninject Interception,每次调用ASP.NET WebApi控制器的某个操作方法时,我们公司都需要记录某些事情。由于我们现在使用Ninject进行DI,因此我们也希望将其用于此目的。这就是我迄今为止所尝试的 我通过NuGet安装了Ninject、Ninject.Extensions.Interception和Ninject.Extensions.Interception.DynamicProxy,我有以下模块 public class InterceptAllModule : InterceptionModule {

每次调用ASP.NET WebApi控制器的某个操作方法时,我们公司都需要记录某些事情。由于我们现在使用Ninject进行DI,因此我们也希望将其用于此目的。这就是我迄今为止所尝试的

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

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关于需要动作方法是虚拟的,并放入一个空的默认构造函数(只是为了安抚动态代理,保持您的另一个构造函数不动),我已经让动作过滤器和截取方法都起作用了

我想说的是,目前为止,您的代码将拦截ApicController上可能不需要的方法,因此您可能还需要放置一些代码来过滤这些方法,例如ExecuteAsync和Dispose

我唯一的另一点是性能巨大免责声明这些只是非常基本的测试(每次使用操作过滤器方法记录统计数据),我邀请您自己做(!)。。。但是使用DynamicProxy拦截器,我得到了每个get请求大约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.]
注释掉截取代码并使用动作过滤器,我获得了亚毫秒的性能:

[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了吗?这是MVC操作上AOP的自然扩展点

如果您对控制器上的实际操作以外的方法感兴趣,那么我会理解,但我想我还是会发布一个建议

受到和的启发

更新以显示标记方法时计时器的排除。核心WebApi框架的启示

全局注册此项,以便所有操作都受此项监控:

GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());
然后:

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

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

对于仍然潜伏的人来说,我想使用Ninject的原因是我可以向拦截器中注入一个记录器(或其他任何东西),但我想拦截所有动作

Mark的答案是完美的,但不是使用

GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());
使用Ninject绑定过滤器

Kernal.BindHttpFilter<TimingActionFilter>(FilterScope.Action).
Kernal.BindHttpFilter(FilterScope.Action)。

您需要在TimingActionFilter类中创建一个适当的构造函数。

也许这一建议在设计上有太大的改变,但是当您将所有业务操作抽象到一个通用抽象之后,并将其注入控制器中时,您将能够轻松地装饰或截取这些抽象,以添加横切关注点,例如您的计时方面。请看一看,以了解我在说什么。您是否有其他无参数构造函数,并且所有操作方法都是虚拟的?感谢Remo,我向所有操作方法添加了虚拟的,但是对于无参数构造函数,我遇到了一个问题,因为我们的服务对象正在那里注入并在控制器中使用。对于无参数构造函数,服务对象为null。你如何避开这个问题?非常感谢+你好,马克,我感谢你的回答。但我的经理不想使用“操作筛选器”属性。他希望所有的动作方法都被记录下来,除了那些我们标记属性[nolog]的动作方法。@ray247,谢谢你让我提出建议。一便士换一英镑,我已经更新以显示使用这种方法的NoLog能力。我也会很快用一些Ninject的例子更新答案。谢谢大家。我还没有试过你的代码,但是我完全同意你上面展示的代码。GlobalConfiguration.Configuration.Filters.Add将使每个操作都发生,而NoLog属性将过滤掉我们不需要的操作。一位同事提供了一个带有HttpModule的解决方案,可以拦截每个请求。但是对于MVC项目来说,您的更自然。谢谢你,祝你新年快乐。标记为答案@MarkJones,你认为你能帮我解决这个问题吗?如果你能走这条路,听起来是OWIN中间件的一个很好的例子。
GlobalConfiguration.Configuration.Filters.Add(new TimingActionFilter());
Kernal.BindHttpFilter<TimingActionFilter>(FilterScope.Action).