ActionFilterAttribute 是否为每个动作实例化?

Is ActionFilterAttribute instantiated for each action?

我想在 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;
            }
        }

不要那样做,因为属性是静态定义的。您需要将其存储在请求中,例如 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);
}

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

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

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