Asp.net-Mvc

使用輸出記憶體和其他操作過濾器

  • November 6, 2018

我在我的應用程序中的幾個操作中添加了輸出記憶體,以便輕鬆提升性能。但是,這些操作還需要在每次請求後通過點擊 Redis 數據庫來增加一個計數器(它是一個視圖計數器)。

起初,我想我可以調整操作過濾器的執行順序,以確保計算視圖:

public class CountersAttribute : ActionFilterAttribute
{
   public override void OnResultExecuted(ResultExecutedContext filterContext)
   {
       //increment my counter all clever like
       base.OnResultExecuted(filterContext);
   }
}

但這沒有用;顯然,OutputCacheAttribute 的行為不像正常的操作過濾器。然後我嘗試實現自定義輸出記憶體:

public class OutputCacheWithCountersAttribute : OutputCacheAttribute
{
   public override void OnResultExecuted(ResultExecutedContext filterContext)
   {
       //straight to the source to get my headcount!
       base.OnResultExecuted(filterContext);
   }
}

不,也沒有用;一旦記憶體了動作,動作過濾器似乎就被完全忽略了。真可惜。

那麼,呃,我有什麼辦法(不實現自定義輸出記憶體提供程序)來確保我的視圖被正確計數,並且乾淨且合理?

順便說一句,它OutputCacheAttribute有一些限制,Paul Hiles 開發的一個名為DonutOutputCache的自定義屬性有助於克服這些限制。

它支持的一項重要功能是您可以擁有一個可以一直呼叫的操作過濾器,即使該操作是否標有記憶體屬性。

例如。您希望將操作記憶體 5 秒,同時您希望在每次操作使用LogThis過濾器收到請求時記錄下來,您可以通過以下方式簡單地實現這一點,

[LogThis]
[DonutOutputCache(Duration=5, Order=100)]
public ActionResult Index()

保羅

是的,與內置的 OutputCacheAttribute 不同,即使從記憶體中檢索到頁面,操作過濾器也會執行。唯一需要補充的是,您確實需要注意過濾器順序。如果您的操作過濾器實現 OnResultExecuting 或 OnResultExecuted,那麼這些方法將在所有情況下執行,但對於 OnActionExecuting 和 OnActionExecuted,它們只會在過濾器在 DonutOutputCacheAttribute 之前執行時執行。這是由於 MVC 在設置 filterContext.Result 屬性時阻止後續過濾器執行的方式,這是我們需要為輸出記憶體執行的操作。

我認為您不能依賴在動作或控制器上定義動作過濾器的順序。為了確保一個過濾器在另一個過濾器之前執行,您可以使用所有 ActionFilterAttribute 實現中存在的 Order 屬性。任何未設置 order 屬性的操作,預設值為 -1,這意味著它們將在具有顯式 Order 值的過濾器之前執行。

因此,在您的情況下,您只需將 Order=100 添加到 DonutOutputCache 屬性,所有其他過濾器將在記憶體過濾器之前執行。

引用自:https://stackoverflow.com/questions/10990337