ASP.NET Advent Calendar 2016 - Qiitaの21日目の投稿となります。 テーマをガラッと変えました。
ASP.NET Core MVCのコントローラから返されるHTTPレスポンスヘッダのCache-Controlを設定してみます。
Cache-Control
Cache-Controlは、ブラウザ(やキャッシュサーバ)へキャッシュの利用有無や有効期限などの情報を提供する、HTTPヘッダです。 ブラウザの開発者モードで確認できます。
詳しくはRFC7234を見てください。
ResponseCacheAttribute
ASP.NET CoreのCache-Controlでは、従前のOutputCacheAttibuteクラス(System.Web.Mvc)が使えず、代わりにResponseCacheAttibuteクラス(Microsoft.AspNetCore.Mvc)が提供されています。
キャッシュの有効化と無効化
まずはブラウザに30秒間キャッシュさせる方法を見てみましょう。
- Durationパラメータにキャッシュする秒数を指定します。
[ResponseCache(Duration = 30)] public IActionResult Index() { return View(); }
max-age
にてキャッシュの有効期限が指定されます。public
の詳細は後述。
次に、常に更新を確認し、更新が無い場合にはキャッシュを使う設定です。
Duration
パラメータを0とする。Location
パラメータをResponseCacheLocation.Noneとする。
[ResponseCache(Location = ResponseCacheLocation.None, Duration = 0)] public IActionResult Index() { return View(); }
max-age=0
で、常に有効期限切れのキャッシュとなる。no-cache
の有無による違いは無いはずですが、ブラウザの実装に依存します。
なお、更新の検知ではレスポンスヘッダのLast-Modified
(最新更新日時)やETag
(ファイルハッシュ値)が使われます。
次回以降のリクエストヘッダにIf-Modified-Since
にLast-Modified
、If-None-Match
にETag
の値が設定され、サーバ側で比較して更新があった(サーバ側の最新の値と一致しない)場合のみ新しいレスポンスを返します。
最後に、一切キャッシュさせない設定です。
NoStore
パラメータをtrueとする
[ResponseCache(NoStore = true)] public IActionResult Index() { return View(); }
no-store
でブラウザは常にサーバから再取得する(=一切キャッシュを使わない)
Location
キャッシュ場所をLocationパラメータで設定します。
- ResponseCacheLocation.None:
no-store
- ResponseCacheLocation.Client:
private
- クライアント(=ブラウザ)のみにキャッシュされる。
- ResponseCacheLocation.Any:
public
- クライアントとキャッシュサーバ(=プロキシサーバなど)の両方でキャッシュされる。
[ResponseCache(Location = ResponseCacheLocation.Client, Duration = 120)] public IActionResult Index() { return View(); }
Cache-Control: private, max-age=120 Pragma: no-cache
CacheProfileName
コントローラのメソッドやクラスを跨いで使う設定については、名前を付けて参照することができます。
- Startup#ConfigureServices内で下記のように設定します。
- ここでは120秒でキャッシュする"Default"という名前の設定を追加。
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(options => { options.CacheProfiles.Add("Default", new Microsoft.AspNetCore.Mvc.CacheProfile() { Duration = 120 }); }); } }
- コントローラクラスやメソッドにてCacheProfileNameパラメータで名前を指定する。
[ResponseCache(CacheProfileName = "Default")] public class HomeController : Controller { public IActionResult Index() { return View(); } }
まとめ
ASP.NET CoreにてCache-Controlを制御する方法について調べてまとめてみました。
とはいえ、ブラウザの実装依存の部分も多々ありますので、ヘッダが正しく設定されていること、そして意図通りにキャッシュにアクセスされていることを開発者モードなどで確認することをおすすめします。