.NET TIPS

[ASP.NET]ページ内の一部分だけをキャッシュから除外するには?[2.0のみ、C#、VB]

山田 祥寛
2006/01/13

 ASP.NETには「ページ・キャッシュ」「データ・キャッシュ」などさまざまなキャッシュ技術が用意されているが(詳細はTIPS「[ASP.NET]データセットをキャッシングするには?」「[ASP.NET]リクエスト・パラメータごとにページをキャッシングするには?」を参照)、その中でもフラグメント・キャッシュは特徴的なキャッシュ技術の1つだ。

 フラグメント・キャッシュとは、ページの断片(フラグメント)単位に異なるキャッシュ・ポリシーを設定するための仕組みである。フラグメント・キャッシュを利用することで、ページ全体に対して一律のキャッシュ・ポリシーを設定する場合に比べ、個々のコンテンツに即したより効果的なキャッシングが可能になる。詳細については、「TIPS:[ASP.NET]Webフォーム・ページの一部分を断片的にキャッシングするには?」を参照するとよいだろう。

 もっとも、ASP.NET 1.xのフラグメント・キャッシュには課題もあった。例えば、キャッシュを利用したページの中でほんの一部分だけダイナミックな情報を出力したいという場合にも、ASP.NET 1.xではその一部分のコンテンツのためだけに、わざわざユーザー・コントロールを定義するしかなかった。しかし、出力する対象がごく単純な文字列である場合、いちいちユーザー・コントロールとして外部化することは、かえってアプリケーションの管理を煩雑にする原因にもなる。これを忌避して、そもそもページ全体でキャッシュを無効にしてしまったという諸兄も多いのではないだろうか。

 そこでASP.NET 2.0で新たに登場したのが、SubstitutionコントロールとWriteSubstitutionメソッドだ。これらを利用することで、ページ上で設定されたキャッシュ・ポリシーにかかわらず、Substitutionコントロールで定義された部分だけを常に動的に生成できるようになる。

●Substitutionコントロールを使用した例

 それではさっそく、具体的な例を見てみよう。まずはSubstitutionコントロールからだ。

<%@ Page Language="C#" %>
<%@ OutputCache VaryByParam="none" Duration="120" %>
<script runat="Server">
// Labelコントロールに現在時刻を表示
void Page_Load(Object sender, EventArgs e) {
  lblTime.Text = DateTime.Now.ToString();
}
// Substitutionコントロールから呼び出されるコールバック・メソッド
// 戻り値として、現在時刻を返す
static String GetTime(HttpContext context) {
  return DateTime.Now.ToString();
}
</script>
<html>
<head>
<title>Substitutionコントロールによるキャッシュ除外</title>
</head>
<body>
現在時刻(キャッシュ有):
<asp:Label id="lblTime" Runat="Server" /><br />
現在時刻(キャッシュ無):
<asp:Substitution id="sbt" Runat="Server" MethodName="GetTime" />
</body>
</html>
Substitutionコントロールを利用したキャッシュ除外の例(C#版:substitution_cs.aspx)
 
<%@ Page Language="VB" %>
<%@ OutputCache VaryByParam="none" Duration="120" %>
<script runat="Server">
' Labelコントロールに現在時刻を表示
Sub Page_Load(sender As Object, e As EventArgs)
  lblTime.Text = DateTime.Now.ToString()
End Sub
' Substitutionコントロールから呼び出されるコールバック・メソッド
' 戻り値として、現在時刻を返す
Shared Function GetTime(context As HttpContext) As String
  Return DateTime.Now.ToString()
End Function
</script>
<html>
<head>
<title>Substitutionコントロールによるキャッシュ除外</title>
</head>
<body>
現在時刻(キャッシュ有):
<asp:Label id="lblTime" Runat="Server" /><br />
現在時刻(キャッシュ無):
<asp:Substitution id="sbt" Runat="Server" MethodName="GetTime" />
</body>
</html>
Substitutionコントロールを利用したキャッシュ除外の例(VB版:substitution_vb.aspx)

 Substitutionコントロールはとても単純なコントロールだ。id、runatなどコントロール共通の属性を除けば、MethodName属性にSubstitutionコントロールから呼び出されるコールバック・メソッドの名前(ここではGetTime)を指定すればよい。Substitutionコントロールは、自分自身が呼び出されるたびにMethodNameプロパティで指定されたメソッドを呼び出し、そのメソッドから返された文字列を「常に動的に」出力するというわけだ。

 後は、Substitutionコントロールによって呼び出されるコールバック・メソッドを記述するだけだ。コールバック・メソッドはページ上(またはユーザー・コントロール)で定義された静的メソッドである必要がある。また、そのシグネチャは、HttpResponseSubstitutionCallbackデリゲートのそれ(パラメータとしてHttpContextオブジェクトを受け取り、戻り値としてString型を返す)と一致していなければならない点に注意してほしい。

 以上を理解したら、さっそくsubstitution_cs.aspx/substitution_vb.aspxを実行してみよう。初回のアクセスでは、Labelコントロール、Substitutionコントロールともに同じ時刻が表示されているが、リフレッシュしてみると、Substitutionコントロールの時刻だけが(キャッシュ・ポリシーにかかわらず)更新されているのが確認できるだろう。

substitution_cs.aspx/substitution_vb.aspxの実行結果
上の画面が初回アクセス時の、下の画面が2回目のアクセス時の実行結果だ。2回目のアクセスでは、Substitutionコントロール上の時刻だけが更新されていることが確認できる。
 
[参考]

ちなみに、AdRotatorは、キャッシュ除外のサポートを内部的に実装しているコントロールだ。つまり、AdRotatorコントロールによる出力は、キャッシュ・ポリシーにかかわらず、常に動的に生成される。

●WriteSubstitutionメソッドを使用した例

 Substitutionコントロールと同様の処理は、Response.WriteSubstitutionメソッドを利用することでも実現できる。以下は、先ほどのサンプル・コードをWriteSubstitutionメソッドで書き換えたものだ。

 なお、本サンプル・プログラムではコード簡略化のために、<%〜%>ブロックによるHTML埋め込み型の記法を採用しているが、<%〜%>はもともと、旧来のASP 3.0との互換性のためにのみ残された記法である。ASP.NETでは推奨されないことを、あらためてここで確認しておきたい。

<%@ Page Language="C#" %>
<%@ OutputCache VaryByParam="none" Duration="120" %>
<script runat="Server">
// Labelコントロールに現在時刻を表示
void Page_Load(Object sender, EventArgs e) {
  lblTime.Text = DateTime.Now.ToString();
}
// WriteSubstitutionメソッドから呼び出されるコールバック・メソッド
// 戻り値として、現在時刻を返す
static String GetTime(HttpContext context) {
  return DateTime.Now.ToString();
}
</script>
<html>
<head>
<title>Substitutionコントロールによるキャッシュ除外</title>
</head>
<body>
現在時刻(キャッシュ有):
<asp:Label id="lblTime" Runat="Server" /><br />
現在時刻(キャッシュ無):
<% Response.WriteSubstitution(
  new HttpResponseSubstitutionCallback(GetTime)); %>
</body>
</html>
WriteSubstitutionメソッドを利用したキャッシュ除外の例(C#版:writeSubstitution_cs.aspx)
 
<%@ Page Language="VB" %>
<%@ OutputCache VaryByParam="none" Duration="120" %>
<script runat="Server">
' Labelコントロールに現在時刻を表示
Sub Page_Load(sender As Object, e As EventArgs)
  lblTime.Text = DateTime.Now.ToString()
End Sub
' WriteSubstitutionメソッドから呼び出されるコールバック・メソッド
' 戻り値として、現在時刻を返す
Shared Function GetTime(context As HttpContext) As String
  Return DateTime.Now.ToString()
End Function
</script>
<html>
<head>
<title>Substitutionコントロールによるキャッシュ除外</title>
</head>
<body>
現在時刻(キャッシュ有):
<asp:Label id="lblTime" Runat="Server" /><br />
現在時刻(キャッシュ無):
<% Response.WriteSubstitution( _
  New HttpResponseSubstitutionCallback(AddressOf GetTime)) %>
</body>
</html>
WriteSubstitutionメソッドを利用したキャッシュ除外の例(VB版:writeSubstitution_vb.aspx)

 WriteSubstitutionメソッドを利用することで、Substitutionコントロール同様、リクエストごとに指定されたコールバック・メソッドを呼び出し、常に動的な出力を生成できるようになる。以上のコードを実行し、先ほどと同様の結果が得られれば成功だ。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:Webフォーム 処理対象:キャッシュ
使用ライブラリ:Substitutionコントロール
関連TIPS:[ASP.NET]データセットをキャッシングするには?
関連TIPS:[ASP.NET]リクエスト・パラメータごとにページをキャッシングするには?
関連TIPS:[ASP.NET]Webフォーム・ページの一部分を断片的にキャッシングするには?

この記事と関連性の高い別の.NET TIPS
[ASP.NET]Webフォーム・ページの一部分を断片的にキャッシングするには?
[ASP.NET]サイト共通のキャッシュ・ポリシーを設定するには?
[ASP.NET]リクエスト・パラメータごとにページをキャッシングするには?
[ASP.NET]WebPartsコントロールでパーソナライズ・ページを構築するには?
[ASP.NET]DataGridコントロールのページ移動ボタンをカスタマイズするには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム 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 記事ランキング

本日 月間