ASP.NET Core の応答キャッシュ

作成者: Rick Anderson および Kirk Larkin

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

応答キャッシュを使用すると、クライアントまたはプロキシから Web サーバーに対して行う要求の数が減ります。 応答キャッシュを使用することで、Web サーバーで応答を生成するために実行される作業量も減ります。 応答キャッシュはヘッダーで設定されます。

ResponseCache 属性は、応答キャッシュ ヘッダーを設定します。 クライアントと中間プロキシは、『RFC 9111: HTTP のキャッシュ』に基づいた応答のキャッシュに関するヘッダーに従う必要があります。

HTTP 1.1 キャッシュ仕様に従うサーバー側キャッシュのためには、応答キャッシュ ミドルウェアを使用します。 ミドルウェアで ResponseCacheAttribute プロパティを使用すると、サーバー側キャッシュの動作に影響を与えることができます。

応答キャッシュ ミドルウェア:

  • HTTP キャッシュ ヘッダーに基づくサーバー応答のキャッシュを有効にします。 標準の HTTP キャッシュ セマンティクスを実装します。 プロキシなどの HTTP キャッシュ ヘッダーに基づいてキャッシュします。
  • 通常、ブラウザーによってキャッシュを防ぐ要求ヘッダーが設定されるため、Razor Pages などの UI アプリには有益ではありません。 出力キャッシュは、ASP.NET Core 7.0 以降で使用でき、UI アプリにベネフィットがあります。 出力キャッシュでは、HTTP ヘッダーとは別にキャッシュする必要がある内容が構成によって決定されます。
  • キャッシュの条件が満たされているクライアントからのパブリック GET または HEAD API 要求に役立つ場合があります。

応答のキャッシュをテストするには、Fiddler または要求ヘッダーを明示的に設定できる別のツールを使用します。 キャッシュをテストするには、ヘッダーを明示的に設定することをおすすめします。 詳細については、「 トラブルシューティング」を参照してください。

HTTP ベースの応答キャッシュ

RFC 9111: HTTP のキャッシュ』は、インターネット キャッシュの動作について記述しています。 キャッシュのために使用される主な HTTP ヘッダーは、Cache-Control です。これは、キャッシュのディレクティブを指定するために使用されます。 ディレクティブは、クライアントからサーバーに要求が送られるとき、さらにサーバーからクライアントに応答が返されるときのキャッシュの動作を制御します。 要求と応答はプロキシ サーバー間を移動し、プロキシ サーバーも HTTP 1.1 キャッシュ仕様に準拠している必要があります。

一般的な Cache-Control ディレクティブを次の表に示します。

ディレクティブ アクション
public キャッシュに応答を格納できます。
private 共有キャッシュによる応答の格納は禁止されます。 プライベート キャッシュに応答を格納し、再利用することができます。
max-age クライアントは、経過時間が指定の秒数を超えた応答を受け入れません。 例: max-age=60 (60 秒)、max-age=2592000 (1 か月)
no-cache 要求時: キャッシュに格納された応答を、要求を満たすために使用することはできません。 オリジン サーバーはクライアントに対する応答を再生成し、キャッシュ内に格納されている応答がミドルウェアによって更新されます。

応答時: オリジン サーバー上での検証なしに後続の要求に応答を使用することはできません。
no-store 要求時: キャッシュに要求を格納することは禁止されます。

応答時: キャッシュに応答を一部でも格納することは禁止されます。

キャッシュで役割を果たすその他のキャッシュ ヘッダーを次の表に示します。

ヘッダー 機能
年齢 オリジン サーバーで応答が生成されたか正常に検証されてから以降の推定時間 (秒単位)。
有効期限 それより後は応答が古いと見なされる日時。
Pragma no-cache 動作を設定する場合の HTTP/1.0 キャッシュとの下位互換性を確保するために存在します。 Cache-Control ヘッダーが存在する場合、Pragma ヘッダーは無視されます。
Vary キャッシュされた応答の最初要求と新しい要求の両方で、すべての Vary ヘッダー フィールドが一致しない限り、キャッシュされた応答を送信してはならないことを指定します。

HTTP ベースのキャッシュで要求の Cache-Control ディレクティブに従う

RFC 9111: HTTP のキャッシュ (セクション 5.2. Cache-Control)』には、クライアントから送信された有効な Cache-Control ヘッダーを優先するキャッシュが必要です 。 クライアントは、no-cache ヘッダー値を使用して要求を行うことで、すべての要求に対してサーバーに新しい応答を強制的に生成させることができます。

HTTP キャッシュの目標を考えると、クライアントの Cache-Control 要求ヘッダーに常に従うことは理にかなっています。 公式仕様では、キャッシュはクライアント、プロキシ、およびサーバーのネットワーク全体で要求を満たすための待機時間とネットワーク オーバーヘッドを削減することを目的としています。 これは必ずしもオリジン サーバーの負荷を制御する方法ではありません。

応答キャッシュ ミドルウェアを使用する場合、このキャッシュ動作を開発者が制御することはできません。ミドルウェアは公式のキャッシュ仕様に準拠しているためです。 .NET 7 では、サーバーの負荷をより適切に制御するための出力キャッシュのサポートが追加されました。 詳細については、「出力キャッシュ」を参照してください。

ResponseCache 属性

ResponseCacheAttribute は、応答キャッシュで適切なヘッダーを設定するために必要なパラメーターを指定します。

警告

認証されたクライアントに関する情報を含むコンテンツのキャッシュを無効にします。 キャッシュは、ユーザーの ID またはユーザーがサインイン済みかどうかに基づいて変更されることのないコンテンツに対してのみ有効にする必要があります。

VaryByQueryKeys は、指定されたクエリ キーの一覧の値によって、格納された応答を変化させます。 * の単一の値が指定されている場合、応答はミドルウェアによって、すべての要求クエリ文字列パラメーターに応じて変化させられます。

VaryByQueryKeys プロパティを設定するには、応答キャッシュ ミドルウェアを有効にする必要があります。 そうしないと、ランタイム例外がスローされます。 VaryByQueryKeys プロパティに対応する HTTP ヘッダーは存在しません。 このプロパティは、応答キャッシュ ミドルウェアによって処理される HTTP 機能です。 キャッシュされた応答をミドルウェアで処理するには、クエリ文字列とクエリ文字列値が前の要求と一致する必要があります。 たとえば、次の表に示す一連の要求と結果について考えてみます:

要求 返却元
http://example.com?key1=value1 サーバー
http://example.com?key1=value1 ミドルウェア
http://example.com?key1=NewValue サーバー

最初の要求はサーバーによって返され、ミドルウェアにキャッシュされます。 2 番目の要求は、クエリ文字列が前の要求と一致するため、ミドルウェアによって返されます。 3 番目の要求は、クエリ文字列の値が前の要求と一致しないため、ミドルウェア キャッシュ内に存在しません。

ResponseCacheAttribute は、(IFilterFactory を使用して) Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter を構成および作成するために使用されます。 ResponseCacheFilter は、応答の適切な HTTP ヘッダーと機能を更新する処理を実行します。 フィルターは、次のようになります。

  • VaryCache-ControlPragmaの既存ヘッダーがあれば削除します。
  • ResponseCacheAttribute で設定されたプロパティに基づいて、適切なヘッダーを書き出します。
  • VaryByQueryKeys が設定されている場合は、応答キャッシュの HTTP 機能を更新します。

差異

このヘッダーは、VaryByHeader プロパティが設定されている場合にのみ書き込まれます。 そのプロパティは Vary プロパティの値に設定されます。 次のサンプルでは、VaryByHeader プロパティを使用しています。

[ApiController]
public class TimeController : ControllerBase
{
    [Route("api/[controller]")]
    [HttpGet]
    [ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
    public ContentResult GetTime() => Content(
                      DateTime.Now.Millisecond.ToString());

Fiddler または別のツールを使用して応答ヘッダーを表示します。 応答ヘッダーには、次のものが含まれます:

Cache-Control: public,max-age=30
Vary: User-Agent

上記のコードでは、応答キャッシュ ミドルウェア サービス AddResponseCaching をサービス コレクションに追加する必要があり、UseResponseCaching 拡張メソッドでミドルウェアを使用するようにアプリを構成します。

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddResponseCaching();

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.UseAuthorization();

app.MapControllers();

app.Run();

NoStore および Location.None

NoStore は、他のほとんどのプロパティをオーバーライドします。 このプロパティを true に設定すると、Cache-Control ヘッダーが no-store に設定されます。 LocationNone に設定すると、次のようになります。

  • Cache-Controlno-store,no-cache に設定されます。
  • Pragmano-cache に設定されます。

NoStorefalseLocationNone の場合、Cache-ControlPragmano-cache に設定されます。

NoStore は通常、エラー ページに対して true に設定されます。 以下では、応答を格納しないようにクライアントに指示する応答ヘッダーが生成されます。

[Route("api/[controller]/ticks")]
[HttpGet]
[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]
public ContentResult GetTimeTicks() => Content(
                  DateTime.Now.Ticks.ToString());

上記のコードでは、応答に次のヘッダーが含まれています:

Cache-Control: no-store,no-cache
Pragma: no-cache

ResponseCacheAttribute をすべてのアプリの MVC コントローラーまたは、Razor ページのページ応答に適用するには、MVC フィルターまたは Razor Pages フィルターを使用して追加します。

MVC アプリの場合:

builder.Services.AddControllersWithViews().AddMvcOptions(options => 
    options.Filters.Add(
        new ResponseCacheAttribute
        {
            NoStore = true, 
            Location = ResponseCacheLocation.None
        }));

Razor Pages アプリに適用される方法については、「MVC グローバル フィルター リストへの ResponseCacheAttribute の追加は Razor Pages には適用されない (dotnet/aspnetcore #18890)」を参照してください。 問題のコメントに記載されている例は、最小 API が 6.0 でリリースされる前に、ASP.NET Core を対象とするアプリ用に記述されています。 6.0 以降のアプリの場合は、例中の Program.cs のサービス登録を builder.Services.AddSingleton... に変更します。

Location と Duration

キャッシュを有効にするには、Duration を正の値に設定し、LocationAny (既定値) または Client にする必要があります。 フレームワークによって、Cache-Control ヘッダーが location 値に設定され、その後に応答の max-age が設定されます。

Location のオプションである AnyClient は、Cache-Control ヘッダー値の publicprivate にそれぞれ変換されます。 「NoStore と Location.None」セクションで説明したように、LocationNone に設定すると、Cache-Control および Pragma ヘッダーは両方とも no-cache に設定されます。

Location.Any (Cache-Controlpublic に設定された) は、"クライアントまたは任意の中間プロキシ" が値をキャッシュできることを示します。これには、応答キャッシュ ミドルウェアが含まれます。

Location.Client (Cache-Controlprivate に設定された) は、"クライアントのみ" が値をキャッシュできることを示します。 応答キャッシュ ミドルウェアを含め、中間キャッシュでは値をキャッシュしないようにします。

キャッシュ制御ヘッダーは、いつどのように応答をキャッシュするかについてのガイダンスをクライアントと中間プロキシに提供するだけです。 クライアントとプロキシが『RFC 9111: HTTP のキャッシュ』に従う保証はありません。 応答キャッシュ ミドルウェアは、仕様に定められたキャッシュ規則に常に従います。

次の例は、Duration を設定し、既定の Location 値をそのまま使用して生成されたヘッダーを示しています:

[Route("api/[controller]/ms")]
[HttpGet]
[ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
public ContentResult GetTimeMS() => Content(
                  DateTime.Now.Millisecond.ToString());

上記のコードでは、応答に次のヘッダーが含まれています:

Cache-Control: public,max-age=10

キャッシュ プロファイル

多くのコントローラー アクション属性で応答キャッシュ設定を複製するのではなく、MVC または Razor Pages を設定するときに、キャッシュ プロファイルをオプションとして構成できます。 参照されているキャッシュ プロファイルに見つかった値は、ResponseCacheAttribute で既定値として使用され、属性に指定されたプロパティによってオーバーライドされます。

次の例は、30 秒のキャッシュ プロファイルを示しています:

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCaching();
builder.Services.AddControllers(options =>
{
    options.CacheProfiles.Add("Default30",
        new CacheProfile()
        {
            Duration = 30
        });
});

var app = builder.Build();

app.UseHttpsRedirection();

// UseCors must be called before UseResponseCaching
//app.UseCors();

app.UseResponseCaching();

app.UseAuthorization();

app.MapControllers();

app.Run();

次のコードは、Default30 キャッシュ プロファイルを参照しています:

[ApiController]
[ResponseCache(CacheProfileName = "Default30")]
public class Time2Controller : ControllerBase
{
    [Route("api/[controller]")]
    [HttpGet]
    public ContentResult GetTime() => Content(
                      DateTime.Now.Millisecond.ToString());

    [Route("api/[controller]/ticks")]
    [HttpGet]
    public ContentResult GetTimeTicks() => Content(
                      DateTime.Now.Ticks.ToString());
}

Default30 キャッシュ プロファイルによる結果のヘッダー応答には、次のものが含まれます:

Cache-Control: public,max-age=30

[ResponseCache] 属性は、次のものに適用できます。

  • Razor Pages: 属性をハンドラー メソッドに適用することはできません。 UI アプリで使用されるブラウザーは、応答キャッシュを防止します。
  • MVC コントローラー。
  • MVC アクション メソッド: メソッド レベルの属性は、クラス レベルの属性で指定された設定をオーバーライドします。

次のコードでは、[ResponseCache] 属性をコントローラー レベルとメソッド レベルで適用します:

[ApiController]
[ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
public class Time4Controller : ControllerBase
{
    [Route("api/[controller]")]
    [HttpGet]
    public ContentResult GetTime() => Content(
                      DateTime.Now.Millisecond.ToString());

    [Route("api/[controller]/ticks")]
    [HttpGet]
    public ContentResult GetTimeTicks() => Content(
                  DateTime.Now.Ticks.ToString());

    [Route("api/[controller]/ms")]
    [HttpGet]
    [ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
    public ContentResult GetTimeMS() => Content(
                      DateTime.Now.Millisecond.ToString());
}

その他のリソース

サンプル コードを表示またはダウンロードします (ダウンロード方法)。

応答キャッシュを使用すると、クライアントまたはプロキシから Web サーバーに対して行う要求の数が減ります。 応答キャッシュを使用することで、Web サーバーで応答を生成するために実行される作業量も減ります。 応答キャッシュは、クライアント、プロキシ、ミドルウェアで応答をどのようにキャッシュするかを指定するヘッダーによって制御されます。

[ResponseCache] は、応答キャッシュ ヘッダーの設定に関与します。 クライアントと中間プロキシは、『RFC 9111: HTTP のキャッシュ』に基づいた応答のキャッシュに関するヘッダーに従う必要があります。

HTTP 1.1 キャッシュ仕様に従うサーバー側キャッシュのためには、応答キャッシュ ミドルウェアを使用します。 ミドルウェアは [ResponseCache] プロパティを使用して、サーバー側のキャッシュ ヘッダーを設定することができます。

HTTP ベースの応答キャッシュ

RFC 9111: HTTP のキャッシュ』は、インターネット キャッシュの動作について記述しています。 キャッシュのために使用される主な HTTP ヘッダーは、Cache-Control です。これは、キャッシュの "ディレクティブ" を指定するために使用されます。 ディレクティブは、クライアントからサーバーに要求が送られるとき、さらにサーバーからクライアントに応答が返されるときのキャッシュの動作を制御します。 要求と応答はプロキシ サーバー間を移動し、プロキシ サーバーも HTTP 1.1 キャッシュ仕様に準拠している必要があります。

一般的な Cache-Control ディレクティブを次の表に示します。

ディレクティブ アクション
public キャッシュに応答を格納できます。
private 共有キャッシュによる応答の格納は禁止されます。 プライベート キャッシュに応答を格納し、再利用することができます。
max-age クライアントは、経過時間が指定の秒数を超えた応答を受け入れません。 例: max-age=60 (60 秒)、max-age=2592000 (1 か月)
no-cache 要求時: キャッシュに格納された応答を、要求を満たすために使用することはできません。 オリジン サーバーはクライアントに対する応答を再生成し、キャッシュ内に格納されている応答がミドルウェアによって更新されます。

応答時: オリジン サーバー上での検証なしに後続の要求に応答を使用することはできません。
no-store 要求時: キャッシュに要求を格納することは禁止されます。

応答時: キャッシュに応答を一部でも格納することは禁止されます。

キャッシュで役割を果たすその他のキャッシュ ヘッダーを次の表に示します。

ヘッダー 機能
年齢 オリジン サーバーで応答が生成されたか正常に検証されてから以降の推定時間 (秒単位)。
有効期限 それより後は応答が古いと見なされる日時。
Pragma no-cache 動作を設定する場合の HTTP/1.0 キャッシュとの下位互換性を確保するために存在します。 Cache-Control ヘッダーが存在する場合、Pragma ヘッダーは無視されます。
Vary キャッシュされた応答の最初要求と新しい要求の両方で、すべての Vary ヘッダー フィールドが一致しない限り、キャッシュされた応答を送信してはならないことを指定します。

HTTP ベースのキャッシュで要求の Cache-Control ディレクティブに従う

RFC 9111: HTTP のキャッシュ (セクション 5.2. Cache-Control)』には、クライアントから送信された有効な Cache-Control ヘッダーを優先するキャッシュが必要です 。 クライアントは、no-cache ヘッダー値を使用して要求を行うことで、すべての要求に対してサーバーに新しい応答を強制的に生成させることができます。

HTTP キャッシュの目標を考えると、クライアントの Cache-Control 要求ヘッダーに常に従うことは理にかなっています。 公式仕様では、キャッシュはクライアント、プロキシ、およびサーバーのネットワーク全体で要求を満たすための待機時間とネットワーク オーバーヘッドを削減することを目的としています。 これは必ずしもオリジン サーバーの負荷を制御する方法ではありません。

応答キャッシュ ミドルウェアを使用する場合、このキャッシュ動作を開発者が制御することはできません。ミドルウェアは公式のキャッシュ仕様に準拠しているためです。 サーバーの負荷をより適切に制御するための "出力キャッシュ" のサポートは、ASP.NET Core の今後のリリースに向けての設計提案となっています。 詳細については、出力キャッシュのサポートの追加 (dotnet/aspnetcore #27387)に関するページを参照してください。

ASP.NET Core のその他のキャッシュ テクノロジ

メモリ内キャッシュ

メモリ内キャッシュの場合、キャッシュされるデータはサーバー メモリを使用して格納されます。 この種類のキャッシュは、1 台またはセッション アフィニティを使用する複数のサーバーに適しています。 セッション アフィニティは、スティッキー セッションとも呼ばれます。 スティッキー セッションは、クライアントからの要求が処理のために常に同じサーバーにルーティングされることを意味します。

詳細については、「ASP.NET Core でメモリ内にキャッシュする」と「Azure Application Gateway セッション アフィニティの問題のトラブルシューティング」を参照してください。

分散キャッシュ

アプリがクラウドまたはサーバー ファームでホストされている場合にデータをメモリに格納するには、分散キャッシュを使用します。 このキャッシュは、要求を処理するサーバー間で共有されます。 クライアントのためのキャッシュされたデータが使用可能な場合、クライアントから送信された要求は、グループ内の任意のサーバーで処理できます。 ASP.NET Core は、SQL Server、RedisNCache の分散キャッシュと連携して動作します。

詳細については、「ASP.NET Core の分散キャッシュ」を参照してください。

キャッシュ タグ ヘルパー

キャッシュ タグ ヘルパーを使用して、MVC ビューまたは Razor ページからのコンテンツをキャッシュします。 キャッシュ タグ ヘルパーは、メモリ内キャッシュを使用してデータを格納します。

詳細については、「ASP.NET Core MVC のキャッシュ タグ ヘルパー」を参照してください。

分散キャッシュ タグ ヘルパー

分散キャッシュ タグ ヘルパーを使用して、分散クラウドまたは Web ファームのシナリオで MVC ビューまたは Razor ページからのコンテンツをキャッシュします。 分散キャッシュ タグ ヘルパーは、SQL Server、Redis、または NCache を使用してデータを格納します。

詳細については、「ASP.NET Core の分散型キャッシュ タグ ヘルパー」を参照してください。

ResponseCache 属性

ResponseCacheAttribute は、応答キャッシュで適切なヘッダーを設定するために必要なパラメーターを指定します。

警告

認証されたクライアントに関する情報を含むコンテンツのキャッシュを無効にします。 キャッシュは、ユーザーの ID またはユーザーがサインイン済みかどうかに基づいて変更されることのないコンテンツに対してのみ有効にする必要があります。

VaryByQueryKeys は、指定されたクエリ キーの一覧の値によって、格納された応答を変化させます。 * の単一の値が指定されている場合、応答はミドルウェアによって、すべての要求クエリ文字列パラメーターに応じて変化させられます。

VaryByQueryKeys プロパティを設定するには、応答キャッシュ ミドルウェアを有効にする必要があります。 そうしないと、ランタイム例外がスローされます。 VaryByQueryKeys プロパティに対応する HTTP ヘッダーは存在しません。 このプロパティは、応答キャッシュ ミドルウェアによって処理される HTTP 機能です。 キャッシュされた応答をミドルウェアで処理するには、クエリ文字列とクエリ文字列値が前の要求と一致する必要があります。 たとえば、次の表に示す一連の要求と結果について考えてみます。

要求 結果
http://example.com?key1=value1 サーバーから返されます。
http://example.com?key1=value1 ミドルウェアから返されます。
http://example.com?key1=value2 サーバーから返されます。

最初の要求はサーバーによって返され、ミドルウェアにキャッシュされます。 2 番目の要求は、クエリ文字列が前の要求と一致するため、ミドルウェアによって返されます。 3 番目の要求は、クエリ文字列の値が前の要求と一致しないため、ミドルウェア キャッシュ内に存在しません。

ResponseCacheAttribute は、(IFilterFactory を使用して) Microsoft.AspNetCore.Mvc.Internal.ResponseCacheFilter を構成および作成するために使用されます。 ResponseCacheFilter は、応答の適切な HTTP ヘッダーと機能を更新する処理を実行します。 フィルターは、次のようになります。

  • VaryCache-ControlPragmaの既存ヘッダーがあれば削除します。
  • ResponseCacheAttribute で設定されたプロパティに基づいて、適切なヘッダーを書き出します。
  • VaryByQueryKeys が設定されている場合は、応答キャッシュの HTTP 機能を更新します。

差異

このヘッダーは、VaryByHeader プロパティが設定されている場合にのみ書き込まれます。 そのプロパティは Vary プロパティの値に設定されます。 次のサンプルでは、VaryByHeader プロパティを使用しています。

[ResponseCache(VaryByHeader = "User-Agent", Duration = 30)]
public class Cache1Model : PageModel
{

サンプル アプリを使用して、ブラウザーのネットワーク ツールで応答ヘッダーを表示します。 次の応答ヘッダーは、Cache1 ページの応答と共に送信されます。

Cache-Control: public,max-age=30
Vary: User-Agent

NoStore および Location.None

NoStore は、他のほとんどのプロパティをオーバーライドします。 このプロパティを true に設定すると、Cache-Control ヘッダーが no-store に設定されます。 LocationNone に設定すると、次のようになります。

  • Cache-Controlno-store,no-cache に設定されます。
  • Pragmano-cache に設定されます。

NoStorefalseLocationNone の場合、Cache-ControlPragmano-cache に設定されます。

NoStore は通常、エラー ページに対して true に設定されます。 サンプル アプリの Cache2 ページでは、応答を格納しないようにクライアントに指示する応答ヘッダーが生成されます。

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class Cache2Model : PageModel
{

サンプル アプリは、次のヘッダーを含む Cache2 ページを返します。

Cache-Control: no-store,no-cache
Pragma: no-cache

ResponseCacheAttribute をすべてのアプリの MVC コントローラーまたは、Razor ページのページ応答に適用するには、MVC フィルターまたは Razor Pages フィルターを使用して追加します。

MVC アプリの場合:

services.AddMvc().AddMvcOptions(options => 
    options.Filters.Add(
        new ResponseCacheAttribute
        {
            NoStore = true, 
            Location = ResponseCacheLocation.None
        }));

Razor Pages アプリに適用される方法については、「MVC グローバル フィルター リストへの ResponseCacheAttribute の追加は Razor Pages には適用されない (dotnet/aspnetcore #18890)」を参照してください。

Location と Duration

キャッシュを有効にするには、Duration を正の値に設定し、LocationAny (既定値) または Client にする必要があります。 フレームワークによって、Cache-Control ヘッダーが location 値に設定され、その後に応答の max-age が設定されます。

Location のオプションである AnyClient は、Cache-Control ヘッダー値の publicprivate にそれぞれ変換されます。 「NoStore と Location.None」セクションで説明したように、LocationNone に設定すると、Cache-Control および Pragma ヘッダーは両方とも no-cache に設定されます。

Location.Any (Cache-Controlpublic に設定された) は、"クライアントまたは任意の中間プロキシ" が値をキャッシュできることを示します。これには、応答キャッシュ ミドルウェアが含まれます。

Location.Client (Cache-Controlprivate に設定された) は、"クライアントのみ" が値をキャッシュできることを示します。 応答キャッシュ ミドルウェアを含め、中間キャッシュでは値をキャッシュしないようにします。

キャッシュ制御ヘッダーは、いつどのように応答をキャッシュするかについてのガイダンスをクライアントと中間プロキシに提供するだけです。 クライアントとプロキシが『RFC 9111: HTTP のキャッシュ』に従う保証はありません。 応答キャッシュ ミドルウェアは、仕様に定められたキャッシュ規則に常に従います。

次の例は、サンプル アプリの Cache3 ページ モデルと、Duration を設定し、既定の Location 値をそのまま使用して生成されたヘッダーを示しています。

[ResponseCache(Duration = 10, Location = ResponseCacheLocation.Any, NoStore = false)]
public class Cache3Model : PageModel
{

サンプル アプリからは、次のヘッダーを含む Cache3 ページが返されます。

Cache-Control: public,max-age=10

キャッシュ プロファイル

多くのコントローラー アクション属性で応答キャッシュ設定を複製するのではなく、Startup.ConfigureServices で MVC または Razor Pages を設定するときに、キャッシュ プロファイルをオプションとして構成できます。 参照されているキャッシュ プロファイルに見つかった値は、ResponseCacheAttribute で既定値として使用され、属性に指定されたプロパティによってオーバーライドされます。

キャッシュ プロファイルを設定します。 次の例は、サンプル アプリの Startup.ConfigureServices での 30 秒のキャッシュ プロファイルを示しています。

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddMvc(options =>
    {
        options.CacheProfiles.Add("Default30",
            new CacheProfile()
            {
                Duration = 30
            });
    });
}

サンプル アプリの Cache4 ページ モデルは、Default30 キャッシュ プロファイルを参照します。

[ResponseCache(CacheProfileName = "Default30")]
public class Cache4Model : PageModel
{

ResponseCacheAttribute は以下に対して適用できます。

  • Razor Pages: 属性をハンドラー メソッドに適用することはできません。
  • MVC コントローラー。
  • MVC アクション メソッド: メソッド レベルの属性は、クラス レベルの属性で指定された設定をオーバーライドします。

結果として、Default30 キャッシュ プロファイルによって Cache4 ページの応答に適用されるヘッダーは、次のようになります。

Cache-Control: public,max-age=30

その他のリソース