spacer
spacer
開発者の談話室

nogu: 2008年8月アーカイブ

ASP.NET Event発生順序

|

Microsoft .Net framework ASP.NETでは、ウェブページの表示時に各種オブジェクトによるイベントが発生します。イベントの発生順序を正しく把握していないと、セッション保管しているパラメータや、オブジェクトのパラメータが意図しない値で挙動し、障害の原因となります。

下記の順序でイベントがおこるのはドキュメント(ASP.NET のマスター ページとコンテンツ ページのイベント)に明記されています。

  1. マスタ ページ コントロールの Init イベントが発生します。

  2. コンテンツ コントロールの Init イベントが発生します。

  3. マスタ ページの Init イベントが発生します。

  4. コンテンツ ページの Init イベントが発生します。

  5. コンテンツ ページの Load イベントが発生します。

  6. マスタ ページの Load イベントが発生します。

  7. コンテンツ コントロールの Load イベントが発生します。

  8. コンテンツ ページの PreRender イベントが発生します。

  9. マスタ ページの PreRender イベントが発生します。

  10. マスタ ページ コントロールの PreRender イベントが発生します。

  11. コンテンツ コントロールの PreRender イベントが発生します。

ドキュメントでは、『OnInitイベントは最も内側のコントロールから外側の順序で発生し、それ以外のイベントは最も外側のコントロールから内側の順序で発生します』、と書かれています。

ですが、この記述は間違っています

実際には、ページ内のコントロールのイベント発生順序は、MasterページないのコントロールがContentPlaceHolderの前後のどちらにあったかで、結果が違います。

前置の場合: <uc1:UC_OnChildMaster id="UC_OnChildMaster1" runat="server" Val="1"/> <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" />

後置の場合: <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server" /> <uc1:UC_OnChildMaster id="UC_OnChildMaster1" runat="server" Val="1"/>

 

前置の場合は、ドキュメントの言うとおりに、先にMasterページ内のコントロールUC_OnChildMaster1のOnInitイベントが発生しますが、後置の場合は、コンテンツページ内に配置したコントロールのイベントが先に発生します。

直感として『HTMLに出力する順序でコントロールのイベントが発生する』と覚えておくとよいです。

コントロールの内包関係に関してはMSDNの記述どおり、OnInitでは内側から、それ以外では外側からイベントが発生していきます。

 

同時に覚えておくと便利なので、下記の点も把握しておくと良いです。

1) ディレクティブでのプロパティアクセス

2) ユーザコントロールタグでのプロパティアクセス

3) コード表示ブロック <% %> 

実はこれらの発生順序は下記の順序になっています。

1) → 2) → OnInit → OnLoad → OnPreRender → 3) → OnUnload

1)および2)は、MASTER、ASPX、ASCXファイルなどが読み込まれた時点で即座に解釈されているため、OnInitより先に発生します。

これは、非常に使い勝手がよく、複数のページで共通して使う機能を継承元の親ページで実装している場合に、OnLoadイベントなどの挙動を指定することが可能になります。例えば、Page_Loadで表示データをRepeaterにDataBindするコントロールなどで、表示する個数を指定したいばあいに、コントロールを配置したページないのコードブロックで下記のようにしていしても、ユーザコントロールのOnLoadが先に発生しているので動作を制御することができません。

<% this.DisplayItemCount = 3; %>

そこで、OnLoadよりも先に処理される、下記のような形で指定することになります。

<uc1:ItemList id="ItemList1" runat="server" DisplayItemCount="3" />

継承関係、AutoEventWireapとoverride、DataBindとDataBind式まで含めてオブジェクトへのイベント発生順序を考えるとさらに複雑になります。このあたりを正しく把握しておくと、見通しのよい保守性の高い設計が可能になりますので、是非習得してみてください。

 

問題:
 ASP.NETで携帯向けアプリケーションを作成すると、最近のAU端末ではinputタグに初期の入力文字を指定するための、formatやistyle属性が表示されません。

例:
ASPXファイルの記述
<asp:TextBox istyle="3" ID="TB_Mail" runat="server" />

原因:
 Up.BrowserのVersion6以降では、HTMLレンダリングにSystem.Web.UI.XhtmlTextWriterが用いられているため、istyleなどの非正則属性を除去してしまう。

対策:
 Html32TextWriterもしくはChtmlTextWriterを利用するように設定する。
VS2005以降で開発しているのでしたら、App_Browsersフォルダを追加して、KDDI AU用の定義ファイルを作成してください。

例: <browsers / / /> <browser refid="Up" / / /> <capabilities> <capability name="supportsInputIStyle" value="true" /> </capabilities> <controlAdapters markuptextwritertype="System.Web.UI.ChtmlTextWriter" /> </browser> </browsers>

デフォルト定義されている%Windir%\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers\ 内部のopenwave.browserファイルの407行目を直接編集した場合は、コマンドプロンプトから「aspnet_regbrowsers.exe - i」を実行してください。

<controlAdapters markupTextWriterType="System.Web.UI.XhtmlTextWriter" />
↓変更
<controlAdapters markupTextWriterType="System.Web.UI.ChtmlTextWriter" />

参考情報: 

 MSDN ブラウザ定義ファイルのスキーマ

 



 
spacer
spacer