加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 如何拦截所有的ASP.NET WebApi控制器操作方法调

发布时间:2020-12-16 00:35:06 所属栏目:asp.Net 来源:网络整理
导读:我们公司有必要记录某些事情,每次我们的ASP.NET WebApi控制器的一个动作方法被调用。由于我们现在使用Ninject作为DI,所以我们也希望将其用于此目的。这是我迄今为止所尝试过的。 我有Ninject,Ninject.Extensions.Interception和Ninject.Extensions.Interc
我们公司有必要记录某些事情,每次我们的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框架的灵感来自AllowAnonymousAttribute和AuthorizeAttribute

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

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()
    {
       //
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读