8

MVC4 で使用する MongoDB とメモリを組み合わせた出力キャッシュ プロバイダーを実装しようとしています。これが私の最初の実装です:

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 Web ページを使用する<%@ OutputCache Duration="60" VaryByParam="None" providerName="DiskCache" %>と、ページの上部で使用してそれを実現できますが、MVC の場合、私が見つけた唯一の解決策は、Global.asax のHttpApplication.GetOutputCacheProviderName メソッドをオーバーライドすることです。

[OutputCache] 属性を使用してこれを達成するためのよりエレガントな方法はありますか?

4

3 に答える 3

7

[OutputCache] 属性を使用して OutputCacheProvider を設定するより洗練された方法はありますか?

カスタムの実装と属性OutputCacheProviderでアクションを装飾することの間には関係がないため、答えはノーだと思います (現在の mvc4 リリースではそうではありません) 。OutputCache

カスタム プロバイダーを実装して Get メソッドにログインすることでわかったように、Web サーバーに対して行われたすべての要求が表示されます。OutputCacheすべてのアクションから属性を削除した場合でも、出力ログ ファイルにすべてのリクエストが表示されます。このASP.NET MVC hits outputcache for every actionの答えは、それを確認するのに非常に役立つと思いました。

出力キャッシュプロバイダーを1つだけ実装したいように見えるので、デフォルトプロバイダーを設定せに実装をオーバーライドし続けることが唯一のオプションだと思いますGetOutputCacheProviderName(すでに述べたように)。おそらく、すべてのContentImages、およびScriptを除外するために、このようなもの

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";
}

複数の出力キャッシュ プロバイダーを実装する必要がある場合は、ヘルパーを実装して正しいプロバイダー名を指定する必要があると思います。ただし、ルーティング データを解決した例を次に示します。前の例では、URL を直接見ていました。

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";
}
于 2012-08-13T15:08:34.187 に答える
1

もし私があなたのところにいるなら、私はOutputCachAttributeから継承されたMyOutputCachAttributeを書き込もうとします。これは、そのパラメーターによってプロバイダーを選択します。

于 2012-08-08T07:15:34.057 に答える
0

MSDN マガジンのこの記事を確認してください (分散キャッシュ プロバイダーとして MongoDB と Azure を参照しているソース コードと例を参照) http://msdn.microsoft.com/en-us/magazine/gg650661.aspx

編集

ここで提案されているように、CacheProfile 設定を使用してプロバイダーを指定できますか?

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

于 2012-08-13T09:18:43.657 に答える