簡體   English   中英

為特定控制器操作選擇自定義輸出緩存提供程

[英]Selecting custom output cache provider for specific controller actions

我正在嘗試實現MongoDB / Memory組合輸出緩存提供程序以與MVC4一起使用。 這是我最初的實現:

public class CustomOutputCacheProvider : OutputCacheProvider
{
    public override object Get(string key)
    {
        FileLogger.Log(key);
        return null;
    }

    public override object Add(string key, object entry, DateTime utcExpiry)
    {
        return entry;
    }

    public override void Set(string key, object entry, DateTime utcExpiry)
    {
    }

    public override void Remove(string key)
    {
    }
}

我的網絡配置條目:

<caching>
  <outputCache defaultProvider="CustomOutputCacheProvider">
    <providers>
      <add name="CustomOutputCacheProvider" type="MyApp.Base.Mvc.CustomOutputCacheProvider" />
    </providers>
  </outputCache>
</caching>

以及HomeController中的用法:

[OutputCache(Duration = 15)]
public ActionResult Index()
{
    return Content("Home Page");
}

我的問題是,當我檢查日志文件中所請求的密鑰時,我不僅看到了對主控制器的請求,還看到了所有其他路徑:

a2/  <-- should only log this entry
a2/test
a2/images/test/50115c53/1f37e409/4c7ab27d/50115c531f37e4094c7ab27d.jpg
a2/scripts/jquery-1.7.2.min.js

我想我不應該將CustomOutputCacheProvider設置為Web.Config中的defaultProvider,我無法弄清楚如何指定我想用於特定控制器操作的緩存提供程序。

使用Asp.Net網頁,您可以通過在頁面頂部使用<%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %>來完成它,但對於MVC,我能找到的唯一解決方案是覆蓋Global.asax中的HttpApplication.GetOutputCacheProviderName方法

有沒有更優雅的方法來使用[OutputCache]屬性來實現這一目標?

是否有更優雅的方法使用[OutputCache]屬性設置OutputCacheProvider?

我認為答案是否定的(當前mvc4版本沒有),因為實現自定義OutputCacheProvider和使用OutputCache屬性修飾操作之間沒有任何關系。

正如您通過實現自定義提供程序並登錄 Get方法所發現的那樣,您會看到對Web服務器發出的每個請求。 如果要從所有操作中刪除OutputCache屬性,您仍將在out日志文件中看到每個請求。 我認為這個ASP.NET MVC的答案會針對每個動作點擊outputcache ,這對確認它非常有用。

由於看起來您只想實現一個輸出緩存提供程序,因此我認為您唯一的選擇是設置默認提供程序並繼續覆蓋GetOutputCacheProviderName實現(如您所述)。 也許這樣排除所有內容圖像腳本

public override string GetOutputCacheProviderName(HttpContext context)
{
    string absolutePath = context.Request.Url.AbsolutePath;

    if (absolutePath.StartsWith("/Content/", StringComparison.CurrentCultureIgnoreCase)
        || absolutePath.StartsWith("/Scripts/", StringComparison.CurrentCultureIgnoreCase)
        || absolutePath.StartsWith("/Images/", StringComparison.CurrentCultureIgnoreCase))
        return base.GetOutputCacheProviderName(context);

    return "CustomOutputCacheProvider";
}

如果您需要實現多個輸出緩存提供程序,那么我猜您必須實現一個幫助程序才能為您提供正確的提供程序名稱。 但是這里有一個例子,我已經為你解決了路由數據; 如上一個示例直接查看網址。

public override string GetOutputCacheProviderName(HttpContext context)
{       
    RouteCollection rc = new RouteCollection();
    MvcApplication.RegisterRoutes(rc);
    RouteData rd = rc.GetRouteData(new HttpContextWrapper(HttpContext.Current));

    if (rd == null)
        return base.GetOutputCacheProviderName(context);

    var controller = rd.Values["controller"].ToString();
    var action = rd.Values["action"].ToString();

    if (controller.Equals("Content", StringComparison.CurrentCultureIgnoreCase) 
        || controller.Equals("Scripts", StringComparison.CurrentCultureIgnoreCase) 
        || controller.Equals("Images", StringComparison.CurrentCultureIgnoreCase))
        return base.GetOutputCacheProviderName(context);

    if (controller.Equals("Account", StringComparison.CurrentCultureIgnoreCase))
        return "AccountOutputCacheProvider";
    if (controller.Equals("Something", StringComparison.CurrentCultureIgnoreCase))
        return controller + "OutputCacheProvider";

    return "CustomOutputCacheProvider";
}

如果我在哪里,我會嘗試編寫繼承自OutputCachAttribute的MyOutputCachAttribute,它將通過其參數選擇provider。

查看MSDN雜志上的這篇文章(源代碼和示例引用MongoDB和Azure作為分布式緩存提供程序)可能會提供一些見解http://msdn.microsoft.com/en-us/magazine/gg650661.aspx

編輯

您是否可以使用CacheProfile設置來指定此處建議的提供程序?

http://www.dotnetcurry.com/ShowArticle.aspx?ID=665

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM