連載:〜ScottGu氏のブログより〜

よりクリーンなASP.NET 4 WebフォームのHTMLタグ − クライアントID(VS 2010&.NET 4.0シリーズ)

Scott Guthrie 著/Chica
2010/04/02

 本記事は、Microsoftの本社副社長であり、ASP.NETやSilverlightなどの開発チームを率いるScott Guthrie氏のブログを翻訳したものです。氏の許可を得て転載しています。

 これは、VS 2010および.NET 4リリースに向けたブログ投稿シリーズの第16弾です。

 今回の投稿は、ASP.NET 4のWebフォームにおいて、クリーンで、標準に準拠した、CSSフレンドリなタグを生成させるために行った重要な変更についての最初の投稿となります。今回は、サーバ・コントロールによりクライアントに出力される“ID”属性に関して改善されたコントロールの提供についてカバーします。

 [ブログに加え、現在Twitterを使って簡単な更新やリンク共有を行っています。twitter.com/scottguで、私をフォローしてください。]

クリーンで、標準に準拠した、CSSフレンドリなタグ

 ASP.NET Webフォームについて、開発者からよくある苦情の1つは、サーバ・コントロールを使う際に、それらがクリーンでCSSフレンドリな出力やタグを簡単に生成する機能を持っていないということです。特に、これまでのASP.NETリリースに対する苦情には以下のようなものがあります。

  • HTML内に自動生成されたID属性はJavaScriptを書いたりCSSによりスタイル化したりするのが難しい
  • 特定のコントロールに対して(特にasp:menuコントロール)、意味のあるタグではなく、テーブルを使うためにスタイルの見栄えが悪くなる
  • コントロール上にスタイル・プロパティが設定されていないのに、いくつかのコントロールはインラインのスタイル・プロパティを描画する
  • ViewStateがしばしば理想よりも大きくなる

 ASP.NET 4はそのままで、標準に準拠したページを構築するための改善されたサポートを提供します。ASP.NET 4に組み込みの<asp:>サーバ・コントロールは、よりクリーンなタグを生成し、CSSスタイルをサポートしているので、上記すべての問題に対応する手助けとなります。

既存のASP.NET Webフォーム・アプリケーションをアップグレードするときのタグの互換性

 ASP.NET 4のクリーンなタグについての説明を聞いてよく尋ねられるのは、“すごいね、でも、いまあるアプリケーションはどうなるの? これらの変更/改善はアップグレードしたときに何かを壊したりしないの?”という質問です。

 既存のASP.NET Webフォーム・アプリケーションにあるタグやスタイルを壊さないために、構成フラグであるcontrolRenderingCompatbilityVersion属性をweb.configファイルに導入し、ASP.NET 4アプリケーションでデフォルトの新しいクリーンなタグを使用するか、互換性の理由から以前のASP.NETバージョンで使用していた同じタグを使用するのかを決定できるようにしました。


図1

 controlRenderingCompatbilityVersionフラグをアプリケーションで“3.5”に設定すると、デフォルトで、サーバ・コントロールはVS 2008および.NET 3.5で使用されるのと同じタグ生成の方法で、出力を描画します。controlRenderingCompatbilityVersionフラグをアプリケーションで“4.0”に設定すると、サーバ・コントロールは、XHTML 1.1仕様に厳密に従って、クリーンなクライアントIDを持ち、文法上の正しさを基準として描画し、無用なインラインのスタイルを削除します。

 ASP.NET 4を使用して構築されたすべての新しいASP.NET Webフォーム・アプリケーションについては、このフラグはデフォルトで4.0になります。VS 2010を使用してアップグレードされた以前のアプリケーションについては、下位互換性を保つためにアップグレード・ウィザードでcontrolRenderingCompatbilityVersionフラグは自動的に3.5に設定されます。その後、もしページでCSSを使用して、新しいタグの描画を活用したい場合は、オプションとして、(アプリケーション・レベル、あるいはページごと、もしくはディレクトリ・レベルでのweb.configのスコープで)それを変更できます。

今回のトピックであるクリーンなタグ:クライアントID

 描画されるHTML要素上に、クリーンで予測可能なID属性を持たせる機能は、Webフォームを使うに当たり、開発者から長い間懇願されていたことでした(IDの値が“ctl00_ContentPlaceholder1_ListView1_ctrl0_Label1”というのはあまり好評ではありません)。出力されたIDの値を管理できると、出力されるものに対してクライアント側のJavaScriptを簡単に書け、CSSを使用する要素を簡単にスタイル化できるようになり、巨大なページでは生成されるタグのサイズを全体的に減らすことができます。

■コントロールの新しいClientIDModeプロパティ

 ASP.NET 4は新しいClientIDModeプロパティをコントロールの基本クラス上でサポートします。ClientIDModeプロパティは、描画時にどのようにクライアントIDを生成するべきかを示します。ClientIDModeプロパティでは4つの値をサポートしています。

  • AutoID − .NET 3.5と同じ出力を描画(互換性のためctrl00のようなプレフィックスも描画する自動生成ID)
  • Predictable(デフォルト) − “ctl00”ID文字列や、リスト/コンテナ・コントロールが追加する子IDをすべて削除(例:id="ParentControl_ChildControl")
  • Static − すべてのIDの名前付けの管理を開発者に委ね、コントロールのIDに設定されたものがそのまま描画される(例:id="JustMyId")
  • Inherit − コントロールは親のコンテナ・コントロールの名前付けの動作モードに従うよう

 ClientIDModeプロパティは各コントロール上に直接設定できます(もしくはコンテナ・コントロール内では、その中のコントロールがデフォルトで設定を継承します)。


図2

 ページまたはユーザー・コントロール・レベルでも指定できます(<%@ Page %>または<%@ Control %>ディレクティブを使用)。この場合、ページ/ユーザー・コントロール内のコントロールは設定を継承します(オプションとしてオーバーライドも可能です)。


図3

 または、アプリケーションのweb.config内で設定できます。この場合、アプリケーション内のページは設定を継承します(オプションとしてオーバーライドも可能です)。


図4

 これにより、必要に応じて名前付けの動作をカスタマイズ/オーバーライドする柔軟性が与えられました。

例:非リスト・コントロールのIDを管理するためにClientIDModeプロパティを使用

 では、ページ内で“ID”要素の描画を管理するために、どのようにClientIDModeプロパティを使用するのかを見てみましょう。分かりやすくするために、簡単な“SingleControlExample.aspx”というページを作成します。これは“Site.Master”というマスター・ページをベースにしており、そこには “MainContent”という<asp:content>コンテナ・コントロールが含まれており、“Message”IDを持つ<asp:label>コントロールが1つあります。


図5

 そして、コードビハインド内で以下のような簡単なコードを追加し、実行時にラベルのTextプロパティを動的にひも付けます。


図6

 ASP.NET 3.5を使用してこのアプリケーションを実行している場合(もしくはASP.NET 4アプリケーションで3.5を使用した描画設定を行っているか、ClientIDMode=AutoIDに構成している場合)、クライアントに送られる生成されたタグは以下のようになります。


図7

 このIDはユニークです(これは良いことです)。しかし、“ct100”プレフィックスが付いているため、見た目が少し不格好です(これは良くありません)。

■ASP.NET 4を使用しClientIDModeを“Predictable”に設定したタグの描画

 ASP.NET 4だと、サーバ・コントロールはデフォルトで、それらのIDをClientIDMode="Predictable "を使用して描画します。これによりIDの値はユニークのままでページ上で衝突が起こらないようになりますが、同時にあまり短くならず、より予想可能なIDになります。つまり、上記の<asp:label>コントロールに生成されたタグはASP.NET 4だとデフォルトで以下のようになります。


図8

 “ct100”プレフィックスがなくなっている点にご注目ください。“Message”コントロールは“MainContent”コンテナ・コントロールに埋め込まれているので、デフォルトでIDは“MainContent_Message”というプレフィックスが付き、ページ内のそのほかのコントロールとの潜在的な衝突を避けます。

■ASP.NET 4を使用しClientIDModeを“Static”に設定したタグの描画

 時には、IDの値が階層的にネストされるのではなく、単純に設定したとおりの値でIDを描画したいことがあると思います。これを可能にするには、ClientIDMode=staticを使用します。この場合、サーバ側でコントロールに設定したものとまったく同じものでIDを出力します。ASP.NET 4では、タグは以下のように描画されるようになります。


図9

 このオプションにより、コントロールから発行されるクライアントIDの値を完全に管理できるようになります。

例:データバインドされたリスト・コントロールのIDを管理するためにClientIDModeプロパティを使用

 Webフォームが自動生成したIDで作業する際、歴史的にいえば、データバインドされたリスト/グリッド・コントロールを使用/スタイル化するのが一番難しいとされてきました。ASP.NET 4でListViewコントロールを使用して描画されたIDをカスタマイズするシナリオを見てみましょう。

 以下のコードスニペットはListViewコントロールの例で、データバインドされたコレクションのコンテンツ、この場合には空港を表示します。


図10

 その後、上記のListViewへ動的に空港の一覧をデータバインドするために、コードビハインドに以下のようなコードを書きます。


図11

 実行時には、これはデフォルトで以下のように空港の<ul>によるリストを生成します。ListViewのテンプレートにある<ul>要素と<li>要素はサーバ・コントロールではないため、IDはタグに出力されません。


図12

■各行の項目にクライアントIDを追加

 では、JavaScriptを通じて、それぞれの<li>にプログラムからアクセスするために、クライアントIDを出力に追加したいとしましょう。

 最初にすることは、テンプレート内の各<li>要素がサーバ・コントロールであるとマークし(runat=server属性を加えます)、“airport”のIDをそれぞれに与えます。


図13

 デフォルトでは、ASP.NET 4は以下のようなクリーンなIDを描画します(ctl001のようなIDは描画されません)。


図14

■ClientIDRowSuffixプロパティを使用

 上記のテンプレートは各<li>要素にユニークなIDを生成しますが、JavaScriptを使用してクライアント上でプログラムからアクセスするとしたら、簡単に参照できるように、IDに空港コードを含めたいところです。良いことに、各行の要素のIDをよりうまく管理するために、ASP.NET 4ではデータバインドされたコントロール上でClientIDRowSuffixプロパティを利用して、これを簡単に行えます。

 これを行うために、ListViewコントロール上のClientIDRowSuffixプロパティを“Code”に設定します。これにより、IDを生成するときにAirportクラスからデータバインドされる“Code”プロパティをListViewが使用するようになります。


図15

 “1”、“2”、“3”のような行サフィックスの代わりに、IDに埋め込まれた空港コードを使用します(例えば、_CLE、_CAK、_PDXなど)。


図16

 このClientIDRowSuffixの方法は、GridViewなどのそのほかのデータバインド・コントロールでも使用できます。クライアント上で行要素をプログラムしたい場合や、クリーン/ユニークなIDを簡単にJavaScriptコードから参照したい場合に便利です。

まとめ

 ASP.NET 4では、サーバ・コントロールまたWebフォーム・アプリケーションから非常にクリーンなHTMLタグが生成できるようになります。

 今回の投稿では、サーバ・コントロールに描画されたクライアントIDの値をどのように簡単に管理できるかについてカバーしました。この後の投稿では、ASP.NET 4のリリースに含まれる、そのほかのタグの改善についても、いくつかカバーする予定です。

 Hope this helps,

 ScottEnd of Article

   
 
インデックス・ページヘ  「〜ScottGu氏のブログより〜」


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 記事ランキング

本日 月間