2014-12-25 43 views
9

似乎在ASP.NET Web API(4.0.30506)中有一些我以前没有见过的奇怪行为。ASP.NET Web API缓存跨请求的操作筛选器属性

我看到的是相同的操作过滤器属性实例被重用于Web API请求。如果这个属性被注入到依赖关系中,这尤其是个问题,因为这些依赖关系可能是特定于Web请求的。我知道属性最好是passive,但是我的假设是操作过滤器属性没有被缓存。

我搜索了任何文章,博客文章或描述此事的微软更改日志以及背后的原因,但我找不到一件事。这让我怀疑我的配置是否有什么问题会导致这种情况发生。然而,事情是,我能够在一个新的和空的Visual Studio 2012 Web API项目中重现此问题。

我所做的是使用“Web API”模板使用Visual Studio 2012 ASP.NET MVC 4 Web应用程序项目创建一个新的空项目。它带有Web API 4.0.20710.0 NuGet包。从那以后,我添加了以下属性:

​​

我这个属性添加到ValuesController(默认模板的一部分):

public class ValuesController : ApiController { 
    // GET api/values 
    [TestFilterAttribute] 
    public IEnumerable<string> Get() { 
     return new string[] { "value1", "value2" }; 
    } 

    // ... 
} 

现在,当我启动项目,进入/ API /值并刷新该页面几次,“WAT?”抛出异常。

这是Web API的正常行为,如果是这样,这是什么原因?还是我错过了关于这个变化的一些备忘录?这是否会使Web API特性不适合进行依赖注入?或者我做错了什么?

+2

至于我记得,从asp.net的MVC 2.0来3.0时对我巨大的变化 - http://stackoverflow.com/a/8937793/1679310。而且我会说,以后完全一样适用于API ... –

回答

12

的Web API是建立在MVC的顶部,因此它使用了大量的它的功能。

属性实例可重用性是由MVC 3引入的积极缓存的一部分。这意味着相同的Attribute实例很可能会与其应用于的所有Actions一起使用。 MVC管道将尽最大努力对待你的Attribute类,如Singleton

因为同样Attribute实例被重用,这是构造不叫和id不会增加。例如,如果您在OnActionExecuting内部增加id,则一切都会正常工作。

你仍然可以用你的Attribute做你想做的一切。你只需要记住,你不能保证总是会创建一个新的实例的构造函数不应包含除初始初始化之外的任何内容。

public TestFilterAttribute() { 
    // Instance will be reused thus this will not be called for each Action 
} 

public override void OnActionExecuting(HttpActionContext actionContext) { 
    // Called on each Action 
} 
+3

你不能用你的属性做你想做的一切。特别是,由于这种缓存,你不能正确使用请求作用域依赖关系的依赖注入。这种缓存破坏的常见情况是在认证过滤器中注入EF上下文。 –