2014-12-25 68 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上下文。 –