web-dev-qa-db-ja.com

属性を使用して特定のアクションに対してASP.NET MVCでキャッシュを禁止する

私はASP.NET MVC 3アプリケーションを持っています。このアプリケーションはJQueryを介してレコードを要求します。 JQueryは結果をJSON形式で返すコントローラアクションをコールバックします。これを証明することはできませんでしたが、自分のデータがキャッシュされる可能性があることを心配しています。

キャッシングを特定のアクションにのみ適用し、すべてのアクションには適用しないようにします。

データがキャッシュされないようにするためのアクションを実行できる属性はありますか?そうでない場合、ブラウザがキャッシュされたセットの代わりに毎回新しいレコードのセットを取得するようにするにはどうすればよいですか?

179

JQueryが結果をキャッシュしないようにするために、ajaxメソッドに次のコードを追加してください。

$.ajax({
    cache: false
    //rest of your ajax setup
});

あるいは、MVCでのキャッシュを防ぐために、私たちは独自の属性を作成しました、あなたは同じことをすることができます。これが私たちのコードです:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

それから[NoCache]であなたのコントローラを飾ります。 ORこれをすべて実行するには、次のように、コントローラの継承元の基底クラスのクラスに属性を配置します(ある場合)。

[NoCache]
public class ControllerBase : Controller, IControllerBase

コントローラ全体を装飾するのではなく、キャッシュ不可能にする必要がある場合は、この属性を使用して一部のアクションを装飾することもできます。

ブラウザにレンダリングされたときにクラスやアクションにNoCacheがなく、動作していることを確認したい場合は、変更をコンパイルした後にブラウザで「ハードリフレッシュ」(Ctrl + F5)を実行する必要があります。そうするまでは、ブラウザはキャッシュされた古いバージョンを保持し、「通常の更新」(F5)で更新されることはありません。

295
mattytommo

キャッシュを防ぐために組み込みキャッシュ属性を使用できます。

.net Frameworkの場合:[OutputCache(NoStore = true, Duration = 0)]

.net Coreの場合:[ResponseCache(NoStore = true, Duration = 0)]

ブラウザにキャッシュを無効にさせることは不可能であることに注意してください。あなたができる最善のことは、ほとんどのブラウザが尊重するという提案を、通常はヘッダやメタタグの形で提供することです。このデコレータ属性はサーバのキャッシュを無効にし、このヘッダを追加します:Cache-Control: public, no-store, max-age=0。メタタグは追加されません。必要に応じて、それらをビューに手動で追加できます。

さらに、JQueryや他のクライアントフレームワークは、タイムスタンプやGUIDのようなものをURLに追加することで、ブラウザにキャッシュされたリソースのバージョンを使用させないようにします。これはブラウザに再度リソースを要求させるのに効果的ですが、キャッシュを実際に妨げるわけではありません。

最後にリソースはサーバーとクライアントの間にもキャッシュできることに注意してください。 ISP、プロキシ、その他のネットワークデバイスもリソースをキャッシュし、実際のリソースを見ずに内部ルールを使用することがよくあります。あなたがこれらについてできることはあまりありません。幸いなことに、彼らは通常、数秒や数分といった短い時間枠でキャッシュします。

239
Jaguir

あなたが必要なのは:

[OutputCache(Duration=0)]
public JsonResult MyAction(

コントローラ全体で無効にしたい場合は、

[OutputCache(Duration=0)]
public class MyController

ここでのコメントの議論にもかかわらず、これはブラウザのキャッシュを無効にするのに十分です - これはASP.Netがブラウザにドキュメントの期限が切れることをすぐに伝えるレスポンスヘッダを発行する原因となります。

OutputCache Duration=0 Response Headers: max-age=0, s-maxage=0

47
Chris Moschini

コントローラのアクションでは、ヘッダに次の行を追加します。

    public ActionResult Create(string PositionID)
    {
        Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
        Response.AppendHeader("Expires", "0"); // Proxies.
13
dfortun

これが、mattytommoによって提案されたNoCache属性で、Chris Moschiniの答えからの情報を使って簡略化されています。

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
    public NoCacheAttribute()
    {
        this.Duration = 0;
    }
}
5
Konamiman

MVC6(DNX)の場合、System.Web.OutputCacheAttributeはありません。

注:NoStore Durationパラメーターを設定した場合、考慮されません。初回登録の初期期間を設定し、これをカスタム属性で上書きすることが可能です。

しかし、私たちはMicrosoft.AspNet.Mvc.Filters.ResponseCacheFilterを持っています

 public void ConfigureServices(IServiceCollection services)
        ...
        services.AddMvc(config=>
        {
            config.Filters.Add(
                 new ResponseCacheFilter(
                    new CacheProfile() { 
                      NoStore=true
                     }));
        }
        ...
       )

カスタム属性で初期フィルタを上書きすることは可能です

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class NoCacheAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            var filter=filterContext.Filters.Where(t => t.GetType() == typeof(ResponseCacheFilter)).FirstOrDefault();
            if (filter != null)
            {
                ResponseCacheFilter f = (ResponseCacheFilter)filter;
                f.NoStore = true;
                //f.Duration = 0;
            }

            base.OnResultExecuting(filterContext);
        }
    }

これがユースケースです

    [NoCache]
    [HttpGet]
    public JsonResult Get()
    {            
        return Json(new DateTime());
    }
4
Davut Gürbüz

ブラウザのキャッシュを防止するためのAsp.Net MVC Coreの正しい属性値(Internet Explorer 11を含む):

[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]

microsoftのドキュメントで説明されているように:

ASP.NET Coreの応答キャッシュ - NoStoreとLocation.None

1
Nenad

MVCでの出力キャッシュ

 [OutputCache(NoStore = true、Duration = 0、Location = "None"、VaryByParam = "*")] 
 
 OR 
 [OutputCache(NoStore = true、期間= 0、VaryByParam = "なし")] 
 
1
Deepak