是否为每个操作实例化了 ActionFilterAttribute?

Posted

技术标签:

【中文标题】是否为每个操作实例化了 ActionFilterAttribute?【英文标题】:Is ActionFilterAttribute instantiated for each action? 【发布时间】:2020-02-13 15:48:59 【问题描述】:

我想在 ActionFilterAttribute 中有一个字段,它只与它所在的操作相关,例如

    public class TimedAction : ActionFilterAttribute
    
        long start, end;

        public override void OnActionExecuting(HttpActionContext actionContext)
        
            start = Stopwatch.GetTimestamp();

            base.OnActionExecuting(actionContext);
        

        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        
            base.OnActionExecuted(actionExecutedContext);

            end = Stopwatch.GetTimestamp();
        
    

假设 TimedAction 将为每个 API 调用操作实例化是否安全?

编辑:我将代码更改为此,现在看起来请求是共享的(什么??),当我尝试添加键值对时出现异常:An item with the same key has already been added.

        public override void OnActionExecuting(HttpActionContext context)
        
            var start = Stopwatch.GetTimestamp();

            context.Request.Properties.Add(new KeyValuePair<string, object>("Stopwatch", start));

            base.OnActionExecuting(context);
        

        public override void OnActionExecuted(HttpActionExecutedContext context)
        
            base.OnActionExecuted(context);

            var end = Stopwatch.GetTimestamp();

            object o;
            long start = 0;
            if (context.Request.Properties.TryGetValue("Stopwatch", out o))
            
                start = (long)o;
            
        

【问题讨论】:

给你的类一个构造函数。在其上放置断点,并在调试器中解决 【参考方案1】:

不要这样做,因为属性是静态定义的。您需要将其存储在请求中,例如,HttpContext.Current.Items["SomeKey"]:

public override void OnActionExecuting(HttpActionContext actionContext)

    HttpContext.Current.Items["Now"] = DateTime.UtcNow;

    base.OnActionExecuting(actionContext);


public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)

    var beginning = (DateTime) HttpContext.Current.Items["Now"];

    var end = DateTime.UtcNow;

    var interval = end - beginning;

    base.OnActionExecuted(actionExecutedContext);

【讨论】:

这是在 ASP.NET MVC 中,而不是 ASP.NET Web API,请注意!此代码示例适用于 ASP.NET Web API!请参阅此处的文档:docs.microsoft.com/en-us/previous-versions/aspnet/… 原来如此!我在标签中错过了这一点。无视我。 请查看编辑 - 为什么每次我输入操作时请求都不是新实例? 你试过我的方法了吗?【参考方案2】:

显然我所做的(参见 OP 中的代码)和 @RicardoPeres 方法之间没有区别。

问题是我不小心为一个方法设置了两次属性。

但我觉得里卡多的版本比我的好,所以我保留了它。

【讨论】:

以上是关于是否为每个操作实例化了 ActionFilterAttribute?的主要内容,如果未能解决你的问题,请参考以下文章

我的自定义地形生成插件实例化了很多预制件

即使已经实例化了 ManagedBean(例如在 AJAX 调用上),也会调用 @PostConstruct 方法[重复]

python excel操作总结

如何通过应用程序委托使用托管对象上下文实例化还原的视图控制器?

如何通过指定每个属性及其值来实例化 TypeScript 中的对象?

SOA 架构数据访问