japan.internet.comThe Internet & IT Network
RSS
  • ニュース
  • コラム
  • リサーチ
  • ヘッドライン
  • 特集
  • ブログ
  • プレスリリース
  • 専門チャンネル
  • イベント
  • ランキング
  • ニュースメール
2009年7月4日
文字サイズ文字サイズ小文字サイズ中文字サイズ大
デベロッパー2005年10月25日 10:30

ASP.NET が生成する HTML タグを Firefox や Opera にも対応させる方法

海外海外internet.com発の記事
  • このエントリーを含むはてなブックマーク
  • この記事をクリップ!
  • Buzzurlにブックマーク
  • Yahoo!ブックマークに登録
  • newsing it!
  • この記事をokyuuへインポート

はじめに

 ご存じのとおり、ASP.NET WebページはHTML部分とソースコード部分から成ります。このうち、HTML部分にはHTMLマークアップとWebコントロールが混在していて、誰かがASP.NET Webページを訪れると、そのWebコントロールからHTMLマークアップが生成され、静的HTMLマークアップと合わせて、そのページを要求した訪問者のもとに送られ、ブラウザに表示されます。

 WebコントロールからどのようなHTMLが生成されるかは、ASP.NET Webページを要求したブラウザに依存します。その意味で、これをアダプティブ(適応的)レンダリングと呼びます。たとえば、訪問者がInternet Explorer 6.0を通じてページを要求したのであれば、生成されるマークアップはHTML 4.0準拠のマークアップです。仮にLabel WebコントロールのForeColorプロパティが赤(red)なら、生成されるマークアップは次のようになります。

<span id="controlID" style="color: red">Label Text</span>

 しかし、同じ訪問者がNetscape 4.72を使ったとすれば、生成されるマークアップはHTML 3.2準拠となります。その場合、Label Webコントロールのカラー指定は、<span>style属性によらず、<font>要素で行われます。

<span id="controlID"><font color="red">Label Text</font></span>

 アダプティブなコントロールというのは確かにすぐれたアイデアですが、ASP.NETの既定の実装は必ずしもいいことばかりではありません。というのも、最近普及してきているブラウザ群(MozillaFirefoxNetscapeOperaなどの最近バージョン)に対しては、ASP.NETコントロールが既定でHTML 3.2HTML 4.0でなく)準拠のHTMLを生成するからです。ただ、幸いなことに、個々のWebアプリケーション(あるいはWebサーバー全体)に適切な設定をすれば、これら新しい非Microsoftブラウザに対してもHTML 4.0準拠のHTMLが生成されるように指定できます。以下では、WebコントロールのHTMLを4.0準拠とするか3.2準拠とするか、ASP.NETがどう判断するのかを見ていくことにします。また、Netscape、Opera、Mozillaの最近バージョンに対しても4.0準拠のHTMLマークアップが生成されるよう、Webアプリケーションを設定する方法も見ておくことにします。

Webコントロールのレンダリングの仕組み

 すべてのASP.NET Webページは、直接あるいは間接にSystem.Web.UI.Pageクラスから導かれます。このクラスには、ASP.NET Webページを表現するための基本的なメソッドとプロパティが用意されています。Webサーバーは、ASP.NET Webページへの要求を受信すると、それをASP.NETエンジンに引き渡します。ASP.NETエンジンは要求されたページのPageクラスのインスタンスを作成し、このクラスのProcessRequest()メソッドを呼び出します。

 ProcessRequest()メソッドが呼び出されるところから、このページのライフサイクルが始まります。具体的には、ページのコントロール階層がロードされ、表示状態が復元され、Loadイベントが起こり、Webコントロールイベント群が起こり、表示状態が保存され、ページのレンダリングが完成します。次の図は、ASP.NETページのライフサイクルを示しています。

 本稿では、このライフサイクルの詳細はさして重要ではありませんが、詳しく学びたいという方には、「How ASP.NET Web Pages are Processed on the Web Server」と「The ASP.NET Page Object Model」のページをお勧めします。

 ASP.NET Webページのレンダリングは、次の方法で行われます。まず、PageクラスがSystem.Web.UI.HtmlTextWriterクラスのインスタンスを作成し、そのコントロール階層に含まれるすべてのコントロールのRenderControl()メソッドを再帰的に呼び出して、それにHtmlTextWriterインスタンスを引き渡します。各コントロールは、それぞれのHTMLマークアップを1つの(つまり、同じ)HtmlTextWriterインスタンスの末尾に付加していきます。すべてのコントロールのレンダリングが終わると、PageクラスはそのHtmlTextWriterインスタンスの内容(つまり、ページ全体のHTMLマークアップ)を返します。

HtmlTextWriterによるアダプティブレンダリング

 System.Web.UI名前空間には、Webコントロールレンダリングのためのクラスが2つ含まれています。1つはHtmlTextWriter、もう1つはHtml32TextWriterです。前者がHTML 4.0準拠のマークアップ、後者がHTML 3.2準拠のマークアップのレンダリング用です(Html32TextWriterは、HtmlTextWriterからの派生クラスです)。

 Pageクラスはレンダリング段階に入ると、まず新しいHtmlTextWriterインスタンスを作成します。HtmlTextWriterHtml32TextWriterのどちらのクラスインスタンスを作成するかを判断しなければなりませんが、それにはBrowserオブジェクトのTagWriterプロパティを調べます(Browserオブジェクトには、ASP.NET Webページを要求してきたブラウザを特定するための読み取り専用プロパティがいくつかあります)。Webブラウザの特定には、User-Agent文字列が使われます。

 Webブラウザはページを要求するとき、HTTPヘッダにUser-Agent文字列を含めて送信します。これが、ブラウザの特定に使用されます。たとえば、Internet ExplorerならMozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705; .NET CLR 1.1.4322)、Mozilla FireFoxならMozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.6) Gecko/20040206 Firefox/0.8というUser-Agent文字列を送信します。User-Agent文字列を送信しないブラウザや、「偽の」User-Agent文字列を送信するブラウザもあります。たとえば、Operaでは、IE6のUser-Agent文字列を送信させることができますし、Mozillaにも同様の拡張機能があります(ご使用のブラウザがどのようなUser-Agent文字列を送信するかに興味がある方は、User-Agentのデモを参照してください)。

 ASP.NETエンジンはUser-Agent文字列を調べ、Browserのプロパティの値を特定します。プロパティの1つはTagWriterです。この値は、既定ではブラウザがInternet Explorer 4.0以上の場合のみHtmlTextWriterとなり、その他のブラウザではHtml32TextWriterとなります。しかし、これらの値は幸いなことに設定可能であり、Netscape、Mozilla、Operaの最近バージョンについても、Html32TextWriterではなくHtmlTextWriterクラスを使用するよう指示できます。こうした設定は、「maching.config」ファイルか「Web.config」ファイルの<browserCaps>セクションで行います(「maching.config」で設定を変更すると、そのWebサーバー上のすべてのWebアプリケーションの既定動作が変わります。アプリケーション単位の設定変更には、「Web.config」ファイルを使用してください)。

<browserCaps>要素群の検査

 <browserCaps>要素には、いくつかの<case>要素が含まれています。どの<case>要素にもmatch属性があり、そこに何らかの正規表現が含まれています。ブラウザから送られてきたUser-Agent文字列とこの正規表現が一致すると、一致した<case>要素内部のプロパティ群がBrowserオブジェクトに適用されます。「machine.config」ファイルを見ると、既定では、TagWriterプロパティがHtml32TextWriterクラスに設定されていることがわかります。

<browserCaps>
   ...
   tagwriter=System.Web.UI.Html32TextWriter
   ...
</browserCaps>

 さらに下のほうを見ていくと、Internet ExplorerのUser-Agentに一致する<case>要素も見つかります。そこのTagWriterプロパティはHtmlTextWriterクラスに設定されているはずです。

<browserCaps>
  ...
  <case match="^Mozilla[^(]*(compatible; MSIE <snip>">
      browser=IE
      ...
      tagwriter=System.Web.UI.HtmlTextWriter
  </case>
</browserCaps>

 非Microsoftブラウザでは、TagWriterプロパティが既定値(Html32TextWriter)のままです。

Netscape、Mozilla、Operaに対するHTML 4.0準拠のレンダリング設定

 最近の非MicrosoftブラウザでもHTML 4.0準拠のマークアップが生成されるようにするには、「maching.config」ファイルや「Web.config」ファイルをどう設定すればよいでしょうか。その前に、なぜそのような手間をかける必要があるのかを考えてみましょう。赤いForeColorを持つLabelを表示するとして、ASP.NETがそのLabel<span id="controlID" style="color: red">Label Text</span>としてレンダリングしようが、<span id="controlID"><font color="red">Label Text</font></span>(Netscapeの場合)としてレンダリングしようが、結果的に同じものが表示されるのなら、いっこうにかまわないのではないでしょうか。

 確かに、ForeColorの場合はかまわないでしょう。しかし、LabelBackColorプロパティならどうでしょうか。HtmlTextWriterクラスは、背景色の指定にbackground-colorというCSS設定を使用します。CSSのないHTML要素の場合は、<table>を使うか、何らかの裏技でも使わなければ、背景色を設定する方法がありません。したがって、Html32TextWriterクラスはBackColorプロパティを無視します。4.0準拠のマークアップが望まれる理由は、もう1つあります。それは、HtmlTextWriterなら<div>要素のレンダリングができることです。Html32TextWriterクラスは<div><table>としてレンダリングするので、その結果、状況によっては不都合が生じます。

 以下に、「Web.config」ファイルに追加できる<browserCaps>セクションの一例を示します。この追加により、非Microsoftブラウザを使っている場合でも、WebコントロールからHTML 4.0準拠のマークアップが生成されるようになります。この<browserCaps>セクションでは、TagWriterプロパティ以外にも、Browserオブジェクトのプロパティがいくつか設定されていることに注意してください(この<browserCaps>セクションはRob Eberhardtが作成したもので、ここから入手できます)。

<!-- 2003-12-03, Rob Eberhardt - http://slingfive.com/demos/browserCaps/ -->

<browserCaps>
  <!-- GECKO Based Browsers (Netscape 6+, Mozilla/Firebird, ...) //-->
  <case match="^Mozilla/5.0 ([^)]*) (Gecko/[-d]+)? (?’type’[^/d]*)
([d]*)/(?’version’(?’major’d+)(?’minor’.d+)(?’letters’w*)).*">
    browser=Gecko
    type=${type}
    frames=true
    tables=true
    cookies=true
    javascript=true
    javaapplets=true
    ecmascriptversion=1.5
    w3cdomversion=1.0
    css1=true
    css2=true
    xml=true
    tagwriter=System.Web.UI.HtmlTextWriter
    <case match="rv:(?’version’(?’major’d+)(?’minor’.d+)(?’letters’w*))">
      version=${version}
      majorversion=${major}
      minorversion=${minor}
      <case match="^b" with="${letters}">
        beta=true
      </case>
    </case>
  </case>

  <!-- AppleWebKit Based Browsers (Safari...) //-->
  <case match="AppleWebKit/(?’version’(?’major’d)(?’minor’d+)(?’letters’w*))">
    browser=AppleWebKit
    version=${version}
    majorversion=${major}
    minorversion=0.${minor}
    frames=true
    tables=true
    cookies=true
    javascript=true
    javaapplets=true
    ecmascriptversion=1.5
    w3cdomversion=1.0
    css1=true
    css2=true
    xml=true
    tagwriter=System.Web.UI.HtmlTextWriter
    <case match="AppleWebKit/(?’version’(?’major’d)(?’minor’d+)
(?’letters’w*))( (KHTML, like Gecko) )?(?’type’[^/d]*)/.*$">
      type=${type}
    </case>
  </case>
  <!-- Konqueror //-->
  <case match = "Konqueror/(?’version’(?’major’d+)(?’minor’.d+)
(?’letters’));w*(?’platform’[^)]*)">
    browser=Konqueror
    version=${version}
    majorversion=${major}
    minorversion=${minor}
    platform=${platform}
    type=Konqueror
    frames=true
    tables=true
    cookies=true
    javascript=true
    javaapplets=true
    ecmascriptversion=1.5
    w3cdomversion=1.0
    css1=true
    css2=true
    xml=true
    tagwriter=System.Web.UI.HtmlTextWriter
  </case>
</browserCaps>

さらに先へ――クライアントサイドでの妥当性検査

 Netscape、Opera、Mozillaの最近のバージョンを使っているユーザーに対してHTML 4.0準拠のマークアップが生成されるようにASP.NETを設定することは、最初の重要な一歩です。しかし残念ながら、この変更を加えても、妥当性検査コントロールはクライアントサイド妥当性検査スクリプトを生成しません。これには2、3の困った理由がありますが、それについてはまたの機会に書くことにします。

 そのときまで、ハッピープログラミング!

クライアントサイド妥当性検査についての記事

 私が以前に執筆した記事では、クライアントサイド妥当性検査の実装方法を解説するとともに、ダウンレベルのブラウザではなぜクライアントサイド妥当性検査が動作しないかという理由について述べています。興味のある方は、「Client-Side Validation in Downlevel Browsers」を参照してください。

著者紹介

Scott Mitchell(Scott Mitchell)
このエントリーを含むはてなブックマーク この記事をクリップ!
BuzzurlにブックマークBuzzurlにブックマーク Yahoo!ブックマークに登録
この記事をokyuuへインポート
最新トップニュース
データメーション
【データメーション】
中国が「Green Dam」フィルタ規制を撤回(7月1日)
Graphic Design Forum
【Graphic Design Forum】
Chris Dickman(6月25日)
プライバシー ジャパン・インターネットコム版
【プライバシー ジャパン・インターネットコム版】
グーグル・ストリートビューの問題について総務省の見解(6月23日)
エンジニアの独り言
【エンジニアの独り言】
システムを「使う」時代のエンジニアに求められるもの(6月2日)
最新ハイテク講座
最新ハイテク講座
電気は家庭でつくる時代へ!燃料電池「エネファーム」(7月3日)
アクセス解析で見るWebマーケティング
アクセス解析で見るWebマーケティング
決定力を探るアクセス解析(7月3日)
百式のネットビジネス研究
百式のネットビジネス研究
ファーストフードを高級っぽく盛り付けて紹介している「Fancy Fast Food」(7月3日)
週刊-サイト別アクセス状況データ
週刊-サイト別アクセス状況データ
ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(7月2日)
成約率、反応率を上げる Web 文章術
成約率、反応率を上げる Web 文章術
言葉がダイレクトにキャッシュを生む(7月2日)
不況時代の Web ビジネス最適化講座
不況時代の Web ビジネス最適化講座
アクセス解析エキスパートここだけの話、Web コンシェルジュの“勉強法”こっそり教えます(7月2日)
「Webからの脅威」―その傾向と最新対策
「Webからの脅威」―その傾向と最新対策
不正プログラムの分類(7月1日)
DevX
DevX
JavaScriptとDOMによる動的なWebページの作成(6月30日)
エンジニア転職ノウハウ開発室
エンジニア転職ノウハウ開発室
今のままで大丈夫?3匹の子ブタ的キャリア危険度診断(6月30日)
アイレップの SEM フロンティア
アイレップの SEM フロンティア
Web サイトは「無駄な穴のたくさん開いたじょうご」〜サイト成果向上の基本的な考え方(6月30日)
Copyright 2009 Japan Internet.com K.K. All Rights Reserved.http://www.internet.com/