.NET TIPS [ASP.NET]サイト共通のレイアウト部分を部品化するには?山田 祥寛2004/10/22 |
|
|
開発生産性、あるいは、エンド・ユーザーのアクセシビリティといった観点から、テンプレートを用いてサイト・デザインの統一を図る手法は一般的だ。
例えば、以下のようなサイトを想定してほしい。ヘッダ/メニュー部をサイト全体で統一し、コンテンツ部分だけをページごとに切り替えることで、開発者は本来の仕事内容であるコンテンツ作成に集中することができるし、サイト構成が一貫していることから、エンド・ユーザーも直感的にページを行き来できるようになる。また、サイト全体のデザインを変更したいという場合に、共通化されたヘッダ/メニュー部を一元的に更新できるというメリットもあるだろう。
ヘッダ/メニュー部をテンプレートにより統一したサイト |
開発生産性やユーザビリティの観点から、テンプレートを用いてデザインの統一を図る手法は一般的に行われている。 |
ASP.NET 1.1では厳密な意味では、サイト共通のデザインを「テンプレート」化する機能は用意されていないが、その代替機能として「ユーザー・コントロール」が用意されている。「ユーザー・コントロール」は、いうなれば「断片的なWebフォーム」とでも思っていただければよいだろう。実際、見掛けも仕組みもほとんど「.aspx」ファイルと変わらない。ユーザー・コントロールを用いることで、上述したようなサイト共通のレイアウト部分を容易に部品化することができるというわけだ。
以下に具体的なユーザー・コントロールの例を見てみることにしよう。ここでは、あらかじめデータベース・サーバに用意されたmenuテーブルから簡単なナビゲート・バーを作成する。menuテーブルのレイアウトは、以下のとおり。
フィールド名 | データ型 | 概要 |
title | VARCHAR(50) | タイトル |
url | VARCHAR(255) | リンク先のURL(主キー) |
indexNumber | int | 表示順 |
target | VARCHAR(10) | リンク時のターゲット(_blank、_selfなど) |
menuテーブルのフィールド・レイアウト |
|
|
menuテーブルから取得した情報を基にナビゲート・バーを生成するユーザー・コントロール(C#:header_cs.ascx) |
|
|
menuテーブルから取得した情報を基にナビゲート・バーを生成するユーザー・コントロール(VB.NET:header_vb.ascx) |
上述したように、ユーザー・コントロールの記述はWebフォームに限りなく酷似しているが、構文的に異なるポイントがいくつかある。ロジックの詳細な流れについては、コード中のコメントを参照していただくとして、ここではユーザー・コントロール固有のポイントに焦点をあててみることにしよう。
(1)拡張子は「.ascx」
Webフォームの拡張子が「.aspx」であるのに対し、ユーザー・コントロールの拡張子は「.ascx」でなければならない。ASP.NETは拡張子が「.ascx」であることをもって、そのファイルがユーザー・コントロールであることを認識するわけだ。
(2)@Pageディレクティブの代わりに、@Controlディレクティブを利用する
.aspxファイルの処理方法を規定するのは、@Pageディレクティブの役割であった。この@Pageディレクティブに相当する機能を提供するのが、@Controlディレクティブである。@Controlディレクティブは、@Pageディレクティブのいわばサブセット的な位置付けであり、@Pageディレクティブと共通の属性を利用可能だ(@Pageディレクティブで利用可能な属性の詳細は、「プログラミングASP.NET―ASP.NETによるWebアプリケーション実践開発講座―」を参照)。
ただし、@Pageディレクティブで定義された属性でもページ全体の処理を規定するようなものについては、@Controlディレクティブでは利用できないので注意が必要だ。以下には、@Pageディレクティブでは使えるが、@Controlディレクティブでは利用できない属性について一覧にまとめておく(逆に、@Pageディレクティブにはなくて、@Controlディレクティブでのみ使える属性はない)。
AutoCompat | Buffer | ClientTarget | CodeBehind |
CodePage | ContentType | Culture | EnableSessionState |
EnableViewStateMac | ErrorPage | LCID | ResponseEncoding |
SmartNavigation | Trace | TraceMode | Transaction |
UICulture | ValidationRequest | ||
@Controlディレクティブでは利用できない@Pageディレクティブの属性 |
なお、@Controlディレクティブは@Pageディレクティブ同様、.ascxファイル内に1回しか記述することができない。また、その性質上、(構文規則ではないが)一般的にはコードの先頭に記述するのが通例だ。
以上のようにして作成したユーザー・コントロールを.aspxファイルで利用するには、以下のように記述すればよい。
|
|
ユーザー・コントロールheader_cs.aspxを利用する.aspxファイル(usrCtrl.aspx) |
ユーザー・コントロールを利用するには、作成した.ascxファイルを@Registerディレクティブにより.aspxファイルに登録するだけだ。@Registerディレクティブで指定する属性は以下のとおり。
属性名 | 概要 |
Tagprefix | ユーザー・コントロールの接頭辞 |
Tagname | ユーザー・コントロールを参照するためのタグ名 |
Src | ユーザー・コントロールを定義した.ascxファイルへのパス |
@Registerディレクティブで利用可能な属性 |
これで、後は通常のサーバー・コントロールとまったく同じ要領でユーザー・コントロールを利用することができる。上のサンプル・コードでは、Src属性にheader_cs.ascxを指定しているが、header_vb.ascxを利用したい場合にはSrc属性だけを変更すればよい。
ただし、ここで(構文規則ではないが)注意していただきたいのは、フォームである<form runat="Server">要素は原則的に.aspxファイルに記述するべきだということだ。構文的には.ascxファイルに記述しても間違いではないが、<form runat="Server">要素は1つの.aspxファイル内に1つしか記述することができない。このため、もしもユーザー・コントロールで<form runat="Server">要素を記述してしまった場合には、.aspxファイル内、または、ほかのユーザー・コントロールで<form runat="Server">要素の配下に記述するべきコントロールがあったとしてもそれらは使用できなくなってしまう。
上記の.aspxファイル(usrCtrl.aspx)を実行すると、次の画面のようになる。先頭の画像と、その下にある横長のメニュー(ナビゲート・バー)が、ユーザー・コントロールにより表示されている部分だ。
ユーザー・コントロールを利用する.aspxファイルの実行結果 |
なお、ASP.NETには、同様の仕組みとしてSSI(Server Side Include)の#IncludeディレクティブやHttpServerUtilityクラス(System.Web名前空間)のExecuteメソッドなども用意されているが、特別な理由がない限り、ユーザー・コントロールを利用するのが好ましい。
というのも、#IncludeディレクティブはあくまでASP.NETとはまったく異なる仕組みであるため、(1)処理上のオーバーヘッドが大きい、(2)外部ファイルに対して任意の拡張子を付けられるため、例えば「.inc」のような拡張子を使用した場合には、ソース・コードが漏えいする危険性がある、などの問題がある。また、Executeメソッドにしても、やはり指定するのは.aspxファイルなので、(3)URLさえ分かってしまえば、外部ファイルに直接アクセスされてしまう恐れがある、などの問題は避けられない。
その点、ユーザー・コントロールの.ascxファイルは、デフォルト設定で直接アクセスは認められていないし、フラグメント・キャッシュを利用することでパフォーマンスを向上することもできるなど、機能的にもセキュリティ的にもほかの2つの方法(#IncludeディレクティブとHttpServerUtilityクラスのExecuteメソッド)と比べて有利であるためだ。ユーザー・コントロールで利用可能なフラグメント・キャッシュについては、後日、「TIPS:[ASP.NET]Webフォーム・ページの一部分を断片的にキャッシングするには?」で紹介している。
カテゴリ:Webフォーム 処理対象:ユーザー・コントロール 使用キーワード:@Controlディレクティブ 使用キーワード:@Pageディレクティブ 使用キーワード:@Registerディレクティブ 使用キーワード:#Includeディレクティブ 使用ライブラリ:HttpServerUtilityクラス(System.Web名前空間) 関連TIPS:[ASP.NET]Webフォーム・ページの一部分を断片的にキャッシングするには? |
「.NET TIPS」 |
- 第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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|