.NET TIPS

[ASP.NET]任意のキーによりページ・キャッシュを切り替えるには?

山田 祥寛
2004/11/26

 「TIPS:[ASP.NET]リクエスト・パラメータごとにページをキャッシングするには?」では、@OutputCacheディレクティブのVaryByParam属性、VaryByHeader属性を用いることで、リクエスト・パラメータやヘッダ情報、ブラウザの単位にキャッシュを切り替える方法について紹介した(Dynamic Output Caching)。@OutputCacheディレクティブを利用することで、動的なページにおいても、ほとんどプログラムレスで適切なページ・キャッシュを実現することが可能となる。

 しかし場合によっては、VaryByParam属性やVaryByHeader属性で指定可能なキーだけでは、キャッシュを振り分けられないようなケースがある。

 例えば、ユーザーのログイン(認証)を必要とするサイトでは、ユーザーの権限(ロール)によってページを振り分けているかもしれない。その場合には、ページもロール単位にキャッシュする必要がある。あるいは、そもそも認証済みユーザーであるか否かによってページ・キャッシュを振り分けたいというケースもあるだろう。

 はたまた、クライアント・サイド・スクリプトに強く依存したページを構築している場合、ブラウザが実装するJavaScript(ECMAScript)のバージョンによって、出力するクライアント・サイド・スクリプトを切り替えたいというケースもある。このような場合には、ECMAScriptのバージョンの単位にページ・キャッシュを振り分けるべきだろう。

 いずれにせよ、こういったシチュエーションでは、VaryByParam属性やVaryByHeader属性でのキー指定だけでは、キャッシュの振り分けを賄うことができない。

 そこで登場するのが、VaryByCustom属性だ。VaryByCustom属性では、キャッシュ・データを振り分けるためのキーを任意に指定することができる(デフォルトでは“Browser”のみを指定可能で、この場合にはクライアント・ブラウザの単位にキャッシュを切り替える)。本稿では、このVaryByCustom属性で指定可能なキーをカスタマイズすることで、任意のキーによってページ・キャッシュを切り替える方法について解説する。

●手順

1. Global.asaxの設定を行う

 VaryByCustom属性により指定可能なキー文字列をカスタマイズする場合には、Global.asaxでHttpApplicationクラス(System.Web名前空間)のGetVaryByCustomStringメソッドをオーバーライドする。

 以下の例では、GetVaryByCustomStringメソッドをオーバーライドして、カスタムのキーとして“ECMA”を設定し、クライアントが実装するECMAScriptのバージョンによってキャッシュを振り分けている。

<%@ Application Description="Insider .NET Sample" %>
<script Language="C#" runat="Server">
public override string GetVaryByCustomString(HttpContext context, string arg){
  if (arg == "ECMA") {
    Version ecma=context.Request.Browser.EcmaScriptVersion;
    return ecma.Major + "." + ecma.Minor;
  }
  return base.GetVaryByCustomString(context, arg);
}
</script>
カスタムのキー文字列を指定するGlobal.asax(C#の場合)
 
<%@ Application Description="Insider .NET Sample" %>
<script Language="VB" runat="Server">
Public Overrides Function GetVaryByCustomString(context As HttpContext, arg As String) As String
  If arg="ECMA" Then
    Dim ecma As Version=context.Request.Browser.EcmaScriptVersion
    Return ecma.Major & "." & ecma.Minor
  End If
  Return MyBase.GetVaryByCustomString(context, arg)
End Function
</script>
カスタムのキー文字列を指定するGlobal.asax(VB.NETの場合)

 GetVaryByCustomStringメソッドは、HTTP要求の情報を保持したHttpContextオブジェクト(この例では「context」)とVaryByCustom属性で指定されたカスタム文字列を表すStringオブジェクト(この例では「arg」)をパラメータとして受け取る。ここでは、VaryByCustom属性で指定された文字列(arg)が“ECMA”であった場合に、クライアントが実装するECMAScriptのバージョンを「<メジャーバージョン>.<マイナーバージョン>」の形式の文字列で返す。ASP.NETでは、実際にはGetVaryByCustomStringメソッドによって返されたこの文字列をキーとしてキャッシング処理を行うというわけだ。

 ちなみに、クライアント・ブラウザの機能構成を取得するには、クライアントに関する情報を保持するHttpBrowserCapabilitiesクラス(System.Web名前空間)を使えばよい。実行中のクライアント・ブラウザの情報を示すHttpBrowserCapabilitiesオブジェクトはHttpRequestクラス(System.Web名前空間)のBrowserプロパティにより取得できる。上記のコードでは、context.Request.BrowserのEcmaScriptVersionプロパティによりECMAScriptのバージョンを取得している。

2. 任意の.aspxファイルで@OutputCacheディレクティブを指定する

 これで、アプリケーション配下の.aspxファイルからカスタムのキー文字列「ECMA」を利用できるようになった。前述のTIPS同様、クライアントが実装するECMAScriptのバージョンごとにキャッシュが切り替わることを確認してみよう。

<%@ Page ContentType="text/html" Language="C#" %>
<%@ OutputCache Duration="120" VaryByParam="None" VaryByCustom="ECMA" %>
<script runat="Server">
void Page_Load(Object sender, EventArgs e) {
  lbl.Text=DateTime.Now.ToString();
}
</script>
<html>
<head>
<title>ページ・キャッシュ</title>
</head>
<body>
最終更新日:<asp:Label id="lbl" runat="Server" />
</body>
</html>
ページ・キャッシュを行うための.aspxファイル(C#:customCache_cs.aspx)
 
<%@ Page ContentType="text/html" Language="VB" %>
<%@ OutputCache Duration="120" VaryByParam="None" VaryByCustom="ECMA" %>
<script runat="Server">
Sub Page_Load(sender As Object, e As EventArgs)
  lbl.Text=DateTime.Now.ToString()
End Sub
</script>
<html>
<head>
<title>ページ・キャッシュ</title>
</head>
<body>
最終更新日:<asp:Label id="lbl" runat="Server" />
</body>
</html>
ページ・キャッシュを行うための.aspxファイル(VB.NET:customCache_vb.aspx)

 @OutputCacheディレクティブに関する詳細は、前述のTIPSを参照していただきたい。VaryByCustom属性を指定した場合にも、Duration属性、VaryByParam属性は必須である点に注意すること。もしもリクエスト・パラメータによる振り分けが不要である場合には、VaryByParam属性の値に“None”を指定すればよい。

3. 複数のブラウザでキャッシュの状態を確認する

 それでは、該当のWebフォーム・ページに続けてアクセスして、キャッシュが有効になっている様子を確認してみよう。ここでは、Internet Explorer 6.0、Netscape Navigator 7.1、Opera 7.53を利用することにする。Internet Explorer 6.0のECMAScriptのバージョンは1.2、ほかのブラウザのECMAScriptは1.3である。

Internet Explorer 6.0でcustomCache_cs.aspxにアクセスしたところ
 
Netscape Navigator 7.1でcustomCache_cs.aspxにアクセスしたところ
 
Opera 7.53でcustomCache_cs.aspxにアクセスしたところ

 ECMAScriptのバージョンが同一であるNetscape NavigatorとOperaとは同一の最終更新日が表示され、Internet Explorerだけが異なる最終更新日となることが確認できるはずだ。これによって、ECMAScriptのバージョンによって、キャッシュ・データが振り分けられていることが確認できる。

 ちなみに、本稿のサンプル・プログラムではカスタム文字列として“ECMA”という1種類だけを設定しているが、GetVaryByCustomStringメソッドの第2パラメータによって処理を切り替えることで、複数のカスタム文字列を設定することも可能だ。例えば、Microsoftが提供するサンプル・アプリケーション「.NET PetShop」では、ログイン状態やそのほかのキーによって細かなキャッシュの制御を実現している。VaryByCustom属性を理解する好例でもあるので、興味のある方は併せて確認してみるとよいだろう。End of Article

カテゴリ:Webフォーム 処理対象:キャッシング
使用キーワード:@OutputCacheディレクティブ
使用ライブラリ:HttpApplicationクラス(System.Web名前空間)
使用ライブラリ:HttpContextクラス(System.Web名前空間)
使用ライブラリ:HttpRequestクラス(System.Web名前空間)
使用ライブラリ:HttpBrowserCapabilitiesクラス(System.Web名前空間)
関連TIPS:[ASP.NET]リクエスト・パラメータごとにページをキャッシングするには?
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]リクエスト・パラメータごとにページをキャッシングするには?
[ASP.NET]Webフォーム・ページの一部分を断片的にキャッシングするには?
バージョン情報ダイアログを作成するには?
[ASP.NET]サイト共通のキャッシュ・ポリシーを設定するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間