WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

ImageButton と W3C 検証

by WebSurfer 2010年7月28日 14:43

ASP.NET の ImageButton コントロールを配置したページを W3C Markup Validation Service で検証すると、「あなたが使用しているドキュメントタイプではサポートされていない属性(border="0")が使われている」というエラーが出ます。

W3C 検証画面

ドキュメントタイプは ASP.NET のデフォルトで、XHTML 1.0 Transitional と宣言しています。border 属性の使用は、Strict ではダメですが、Transitional では許されているはずなんですが・・・

それはともかく、オリジナルの *.aspx コードにはそのような属性を指定していないにも関わらず、何故 ASP.NET が border="0" という古い属性のコードを書き出すのでしょう?

それは、W3C Markup Validation Service から ASP.NET が要求を受けた際、要求元を古いブラウザと解釈するからだそうです。

ちなみに、IE8 や Firefox 3.6.7 などの新しいブラウザから同じページを要求すると、style="border-width:0px;" となって、XHTML1.0 Strict でも有効な HTML/CSS のコードになります。

この件は ASP.NET Forum にもレポートされていて、回避策も書かれています。リンク切れになると困るのでここにもその回避策を書いておきます。(2011/8/20追記: MSDN ライブラリ にも対応方法が書いてありました。下の追記参照)

アプリケーション・ルート直下に App_Browsers フォルダを設け、その中に以下の内容の .browser ファイルを配置します。これによって ASP.NET は W3C Markup Validation Service に対して IE8 や Firefox 3.6.7 と同じコードを送信するようになるはずです。

<browsers>
  <browser id="w3cValidator" parentID="default">
    <identification>
      <userAgent match="^W3C_Validator" />
    </identification>

    <capture>
      <userAgent match="^W3C_Validator/(?'version'(?'major'\d+)(?'minor'\.\d+)\w*).*" />
    </capture>

    <capabilities>
      <capability name="browser" value="w3cValidator" />
      <capability name="majorversion" value="${major}" />
      <capability name="minorversion" value="${minor}" />
      <capability name="version" value="${version}" />
      <capability name="w3cdomversion" value="1.0" />
      <capability name="xml" value="true" />
      <capability name="tagWriter" value="System.Web.UI.HtmlTextWriter" />
    </capabilities>
  </browser>
</browsers>

なお、上記は ASP.NET 3.5 の話で、ASP.NET 4.0 でどうなっているかは未確認です。


------ 2011/8/20 追記 ------

MSDN ライブラリの Visual Studio と ASP.NET の XHTML 標準 の「マークアップ検証に対するブラウザー機能の構成」というセクションに、本件に関する記述がありました。

.NET Framework 4 の記事なので、サーバを ASP.NET 4 にアップグレードしても、ブラウザー定義を追加しての対応は必要なようです。

なお、そこで紹介されている W3C 検証用のブラウザ定義は以下の通りです。

<browsers>
  <browser id="W3C_Validator" parentID="default">
    <identification>
      <userAgent match="^W3C_Validator" />
    </identification>
    <capabilities>
      <capability name="browser" value="W3C Validator" />
      <capability name="ecmaScriptVersion" value="1.2" />
      <capability name="javascript" value="true" />
      <capability name="supportsCss" value="true" />
      <capability name="tables" value="true" />
      <capability name="tagWriter" 
         value="System.Web.UI.HtmlTextWriter" />
      <capability name="w3cdomversion" value="1.0" />
    </capabilities>
  </browser>
</browsers>

W3C のホームページの User's guide for the W3C Markup Validator によると、通常の User-Agent は W3C_Validator/xx.xxxx とのことなので、MSDN ライブラリのブラウザ定義の方が適切だと思います。

Tags: ,

ASP.NET

再帰を使って FindControl

by WebSurfer 2010年7月27日 22:01

先のポストで、特定のコントロールのオブジェクトを取得するには FindControl メソッドを使うと書きましたが、見つけられないケースがあります。

例えば、Wizard コントロールの FinishButton は、Wizard.FindControl メソッドでは見つかりません。

階層構造は以下のようになっていて、FinishButton は FinishNavigationTemplateContainer に含まれています。そこでなら FindControl メソッドで取得できますが、それより上位のコントロールからでは取得できません。

Wizard

WizardChildTable

TableRow

TableCell

FinishNavigationTemplateContainer

この例に限らず、FindControl メソッドでコントロールを見つけられないというケースは結構あると思います。そのあたりの詳しい理由は MSDN ライブラリの 方法: ID を使用してサーバー コントロールにアクセスする を見てください。

そのような場合で、かつ、名前つきコンテナーへの参照が取得できない場合は、上記の MSDN ライブラリの「名前付けコンテナーの内部にあるコントロールの検索」のセクションに書いてあるように、再帰によってコントロールを見つけるメソッドを自力で書いて使うのが確実だと思います。

以下のような感じです。

protected Control FindControlRecursive(Control root, string id)
{
  if (root.ID == id)
  {
    return root;
  }

  foreach (Control ctrl in root.Controls)
  {
    Control foundCtrl = FindControlRecursive(ctrl, id);
    if (foundCtrl != null)
    {
        return foundCtrl;
    }
  }
  return null;
}

Tags:

ASP.NET

ControlCollection 中の Control の取得

by WebSurfer 2010年7月26日 20:51

ASP.NET に関して、MSDN フォーラムに投稿した内容を中心に、今後役に立ちそうなことを備忘録的にまとめてみようと思います。これが第一回目です。

デザイン画面で、例えば ItemTemplate に Button を一つだけドラッグ&ドロップした場合、その Cell の ControlCollection の中で Button は何番目の Control になると思いますか?

Button 一つしか配置していなのだから 1 番目と思うと大違いで、答えは 2 番目なんです。理由は以下のとおりです。

デザイン画面で ItemTemplate を追加して、それに Button をドラッグ&ドロップすると、自動的に改行とインデントが追加されます。ソース画面で見ると以下のようになります。

<ItemTemplate>
    <asp:Button ID="Button1" runat="server" Text="Button" />
</ItemTemplate>

その改行とインデントが LiteralContorol として Button の前後に追加され、Button は ControlCollection の中で 2 番目になるというわけです。

ちなみに、ソース画面で、改行とインデントを削除すると 1 番目になります。

そういうわけで、ControlCollection 中のオブジェクトを取得するのに、Control.Controls[x] のように順番に頼るのは危険で、FindControl メソッドを使うのが正解のようです。

Tags:

ASP.NET

About this blog

2010年5月にこのブログを立ち上げました。その後 ブログ2 を追加し、ここは ASP.NET 関係のトピックス、ブログ2はそれ以外のトピックスに分けました。

Calendar

<<  2017年11月  >>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

View posts in large calendar