Asp.Netページライフサイクル詳細は私に任せます(2)-WebFormページライフサイクルWEBFORM_ASPNETコントロールツリーの生成と役割

28622 ワード

  • 要約
  • ページクラスは、バックグラウンドファイルクラスと組み合わせてページ全体のHTMLのコードとバックグラウンド出力のコードをブラウザに出力する方法ですか?これはAspにかかわる.Netページライフサイクルにおける重要なコンセプトコントロールツリー.サーバはページクラスオブジェクトを反射的に作成しました
  • コンテンツ
  • ページコントロールツリーをDOMツリーと理解できます.まずHTML->HEAD-BODY-FORM...などのノードがあります.DOMツリーにサブノードが含まれるのは、現在のノードを保存するためのChildNodesという属性があり、つまり各ノードに集合があるからです.同様に、コントロールツリーにもサブコントロールを含むセットが必要です.プロパティを見てみましょう.
    public class webform1_aspx : WebForm1, IRequiresSessionState, IHttpHandler
    public class WebForm1 : Page
    public class Page : TemplateControl, IHttpHandler
    public abstract class TemplateControl : Control, INamingContainer, IFilterResolutionService
    public class Control : IComponent, IDisposable, IParserAccessor, IUrlResolutionService, IDataBindingsAccessor, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
    {
        // Fields
        private string _cachedPredictableID;
        private string _cachedUniqueID;
        private ControlCollection _controls;
        private ControlState _controlState;
        private EventHandlerList _events;
        private string _id;
        private Control _namingContainer;
        private OccasionalFields _occasionalFields;
        internal Page _page;
     ..............
    }

    彼らの継承関係から見ると、ページクラスはコントロールを見ることができます.彼はControlクラスを継承しているので、Controlクラスにはサブコントロールを含む重要な属性があります.継承関係:ページクラス->バックグラウンドファイルクラス->Page->TemplateControl->Control.
    ページクラスのコードを見てみましょう.
    public class webform1_aspx : WebForm1, IRequiresSessionState, IHttpHandler
    {
        // Fields
        private static object __fileDependencies;
        private static bool __initialized;
    
        // Methods
        [DebuggerNonUserCode]
        public webform1_aspx();
        [DebuggerNonUserCode]
        private LiteralControl __BuildControl__control2();
        [DebuggerNonUserCode]
        private HtmlHead __BuildControl__control3();
        [DebuggerNonUserCode]
        private HtmlTitle __BuildControl__control4();
        [DebuggerNonUserCode]
        private LiteralControl __BuildControl__control5();
        [DebuggerNonUserCode]
        private LiteralControl __BuildControl__control6();
        [DebuggerNonUserCode]
        private HtmlForm __BuildControlform1();
        [DebuggerNonUserCode]
        private void __BuildControlTree(webform1_aspx __ctrl);
        [DebuggerNonUserCode]
        private HtmlInputText __BuildControltxtName();
        private void __Renderform1(HtmlTextWriter __w, Control parameterContainer);
        [DebuggerNonUserCode]
        protected override void FrameworkInitialize();
        [DebuggerNonUserCode]
        public override int GetTypeHashCode();
        [DebuggerNonUserCode]
        public override void ProcessRequest(HttpContext context);
    
        // Properties
        protected HttpApplication ApplicationInstance { get; }
        protected DefaultProfile Profile { get; }
    }

    簡単に言えばIRequiresSessionStateはこのページをマークしてSessionにアクセスできるようにするために使用され、IHttpHandlerはブラウザが1つの要求をサーバに送信するたびに、サーバがこの要求を処理するために実現しなければならない方法をProcessRequestと呼ぶ.上のコードから、まず最初の方法private LiteralControl_を見てみましょう.BuildControl__control2()
       private LiteralControl __BuildControl__control2()
    {
        LiteralControl __ctrl = new LiteralControl("\r
    \r
    <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r
    \r
    <html xmlns=\"http://www.w3.org/1999/xhtml\">\r
    "); __ctrl.SetTraceData(typeof(TraceData), new TraceData(0x72, 0xae, true)); return __ctrl; }

    __BuildControl__コントロール2()この方法は実は次のものをコントロールセットに追加することです.
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">

    彼らはサーバの操作に関与していないので、直接文字コントロールとして処理し、コストを節約します.次の方法は_BuildControl__Control 3()は、HtmlHeadを返します.これにより、Headノードを作成する方法も提案できます.Headノードには利用_が含まれています.BuildControl__コントロール4()メソッドは、Titleノードを作成し、AddParsedSubObjectメソッドを呼び出してノードを追加します.すべてのサブコントロールは、このメソッドを呼び出して親ノードに追加されます.<pre><code><span style="color: #000000;">[DebuggerNonUserCode] </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> HtmlHead __BuildControl__control3() { HtmlHead __ctrl </span>= <span style="color: #0000ff;">new</span> HtmlHead(<span style="color: #800000;">"</span><span style="color: #800000;">head</span><span style="color: #800000;">"</span><span style="color: #000000;">); HtmlTitle __ctrl1 </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.__BuildControl__control4(); IParserAccessor __parser </span>=<span style="color: #000000;"> __ctrl; __parser.AddParsedSubObject(__ctrl1); __ctrl.SetTraceData(</span><span style="color: #0000ff;">typeof</span>(TraceData), <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800080;">0x120</span>, <span style="color: #800080;">0x33</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> __ctrl; }</span></code></pre> <pre><code><span style="color: #000000;">[DebuggerNonUserCode] </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> HtmlTitle __BuildControl__control4() { HtmlTitle __ctrl </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> HtmlTitle(); __ctrl.SetTraceData(</span><span style="color: #0000ff;">typeof</span>(TraceData), <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800080;">0x13b</span>, <span style="color: #800080;">15</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> __ctrl; } </span></code></pre> <br>次の方法を見てみましょう.BuildControl__コントロール5(),<body>タグもサーバの操作に関与していないため,文字コントロールとして直接追加された.<pre><code><span style="color: #000000;">[DebuggerNonUserCode] </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> LiteralControl __BuildControl__control5() { LiteralControl __ctrl </span>= <span style="color: #0000ff;">new</span> LiteralControl(<span style="color: #800000;">"</span><span style="color: #800000;">\r<br/><body>\r<br/> </span><span style="color: #800000;">"</span><span style="color: #000000;">); __ctrl.SetTraceData(</span><span style="color: #0000ff;">typeof</span>(TraceData), <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800080;">0x153</span>, <span style="color: #800080;">14</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> __ctrl; } </span></code></pre> <br>次はFormタグです.runat=「server」と表記されているので、専門的な方法を使っています.BuildControlform 1()で作成<pre><code><span style="color: #000000;">[DebuggerNonUserCode] </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> HtmlForm __BuildControlform1() { HtmlForm __ctrl </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> HtmlForm(); </span><span style="color: #0000ff;">base</span>.form1 =<span style="color: #000000;"> __ctrl; __ctrl.ID </span>= <span style="color: #800000;">"</span><span style="color: #800000;">form1</span><span style="color: #800000;">"</span><span style="color: #000000;">; HtmlInputText __ctrl1 </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.__BuildControltxtName(); IParserAccessor __parser </span>=<span style="color: #000000;"> __ctrl; __parser.AddParsedSubObject(__ctrl1); __ctrl.SetRenderMethodDelegate(</span><span style="color: #0000ff;">new</span> RenderMethod(<span style="color: #0000ff;">this</span><span style="color: #000000;">.__Renderform1)); __ctrl.SetTraceData(</span><span style="color: #0000ff;">typeof</span>(TraceData), <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800080;">0x161</span>, <span style="color: #800080;">0x153</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> __ctrl; } </span></code></pre> <br>this.__BuildControltxtName()この方法は、<input type="text"id="txtName"runat="server"/>というコントロールを作成するために使用され、コードを参照してください.<pre><code><span style="color: #000000;">[DebuggerNonUserCode] </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> HtmlInputText __BuildControltxtName() { HtmlInputText __ctrl </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> HtmlInputText(); </span><span style="color: #0000ff;">base</span>.txtName =<span style="color: #000000;"> __ctrl; ((IAttributeAccessor) __ctrl).SetAttribute(</span><span style="color: #800000;">"</span><span style="color: #800000;">type</span><span style="color: #800000;">"</span>, <span style="color: #800000;">"</span><span style="color: #800000;">text</span><span style="color: #800000;">"</span><span style="color: #000000;">); __ctrl.ID </span>= <span style="color: #800000;">"</span><span style="color: #800000;">txtName</span><span style="color: #800000;">"</span><span style="color: #000000;">; __ctrl.SetTraceData(</span><span style="color: #0000ff;">typeof</span>(TraceData), <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800080;">0x20f</span>, <span style="color: #800080;">0x31</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> __ctrl; }</span></code></pre> <br>前述したようにrunat=「server」のタグが付いている場合は、バックグラウンドファイルクラスで変数として宣言されます.この方法では、inputコントロールを作成してからbaseに返します.txtName.__ctrl.SetRenderMethodDelegate(new RenderMethod(this._Renderform 1))という行のコードが重要です.それはRenderform 1という方法をRenderMethodという依頼に追加し、固名思義は、提示方法の依頼に追加することであり、私たちのページクラスのコントロールにはRender(提示)方法があり、コントロールツリーを巡ることで、Render方法を呼び出し、生成したHTMLページコードをブラウザに提示する.見てみましょうRenderform 1という方法<pre><code><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> __Renderform1(HtmlTextWriter __w, Control parameterContainer) { </span><span style="color: #0000ff;">base</span>.BeginRenderTracing(__w, <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800000;">"</span><span style="color: #800000;">/WebForm1.aspx</span><span style="color: #800000;">"</span>, <span style="color: #800080;">0x181</span>, <span style="color: #800080;">10</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">)); __w.Write(</span><span style="color: #800000;">"</span><span style="color: #800000;"> \r<br/>\r<br/> </span><span style="color: #800000;">"</span><span style="color: #000000;">); </span><span style="color: #0000ff;">base</span>.EndRenderTracing(__w, <span style="color: #0000ff;">null</span><span style="color: #000000;">); </span><span style="color: #0000ff;">base</span>.BeginRenderTracing(__w, <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800000;">"</span><span style="color: #800000;">/WebForm1.aspx</span><span style="color: #800000;">"</span>, <span style="color: #800080;">0x18b</span>, <span style="color: #800080;">0x7a</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = <span style="color: #800080;">0</span>; i < <span style="color: #800080;">5</span>; i++<span style="color: #000000;">) { </span><span style="color: #0000ff;">base</span>.Response.Write(i + <span style="color: #0000ff;">base</span>.Hello() + <span style="color: #800000;">"</span><span style="color: #800000;"></br></span><span style="color: #800000;">"</span><span style="color: #000000;">); } </span><span style="color: #0000ff;">base</span>.EndRenderTracing(__w, <span style="color: #0000ff;">null</span><span style="color: #000000;">); parameterContainer.Controls[</span><span style="color: #800080;">0</span><span style="color: #000000;">].RenderControl(__w); </span><span style="color: #0000ff;">base</span>.BeginRenderTracing(__w, <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800000;">"</span><span style="color: #800000;">/WebForm1.aspx</span><span style="color: #800000;">"</span>, <span style="color: #800080;">0x240</span>, <span style="color: #800080;">0x31</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">)); __w.Write(</span><span style="color: #800000;">"</span><span style="color: #800000;">\r<br/> <input type=\"text\" id=\"txtPwd\" />\r<br/> </span><span style="color: #800000;">"</span><span style="color: #000000;">); </span><span style="color: #0000ff;">base</span>.EndRenderTracing(__w, <span style="color: #0000ff;">null</span><span style="color: #000000;">); </span><span style="color: #0000ff;">base</span>.BeginRenderTracing(__w, <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800000;">"</span><span style="color: #800000;">/WebForm1.aspx</span><span style="color: #800000;">"</span>, <span style="color: #800080;">0x271</span>, <span style="color: #800080;">13</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">)); __w.Write(</span><span style="color: #0000ff;">base</span><span style="color: #000000;">.strHello); </span><span style="color: #0000ff;">base</span>.EndRenderTracing(__w, <span style="color: #0000ff;">null</span><span style="color: #000000;">); </span><span style="color: #0000ff;">base</span>.BeginRenderTracing(__w, <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800000;">"</span><span style="color: #800000;">/WebForm1.aspx</span><span style="color: #800000;">"</span>, <span style="color: #800080;">0x27e</span>, <span style="color: #800080;">8</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">)); __w.Write(</span><span style="color: #800000;">"</span><span style="color: #800000;">\r<br/> </span><span style="color: #800000;">"</span><span style="color: #000000;">); </span><span style="color: #0000ff;">base</span>.EndRenderTracing(__w, <span style="color: #0000ff;">null</span><span style="color: #000000;">); </span><span style="color: #0000ff;">base</span>.BeginRenderTracing(__w, <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800000;">"</span><span style="color: #800000;">/WebForm1.aspx</span><span style="color: #800000;">"</span>, <span style="color: #800080;">0x286</span>, <span style="color: #800080;">0x1f</span>, <span style="color: #0000ff;">false</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">base</span>.Response.Write(<span style="color: #0000ff;">base</span><span style="color: #000000;">.strHello); </span><span style="color: #0000ff;">base</span>.EndRenderTracing(__w, <span style="color: #0000ff;">null</span><span style="color: #000000;">); }</span></code></pre> <br>RenderTracingメソッドは、レンダリング追跡であり、レンダリングのプロセスを示します.<input type="text"id="txtName"runat="server"/>のほか、残りのFormのサブコントロールはこの方法で痕跡を見つけた.<%=strHello%>は_として解析されるw.Write(base.strHello); ページクラスの<%Response.Write(strHello); %>実は親のResponseを呼び出したのです.Write(),Response.Write()がブラウザに出力できるのは、HtmlTextWriterが原理です.Write().つまり_w.Write(base.strHello)とResponse.Write()メソッドは同じであり,<%=strHello%>を出すことはResponseに等価である.Write(). <br>最後の章で最も重要な方法があります.BuildControlTree()メソッド.ページクラスのすべてのサブコントロールは、この方法でコントロールツリーに構築されます.<pre><code><span style="color: #000000;">[DebuggerNonUserCode] </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> __BuildControlTree(webform1_aspx __ctrl) { </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.InitializeCulture(); LiteralControl __ctrl1 </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.__BuildControl__control2(); IParserAccessor __parser </span>=<span style="color: #000000;"> __ctrl; __parser.AddParsedSubObject(__ctrl1); HtmlHead __ctrl2 </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.__BuildControl__control3(); __parser.AddParsedSubObject(__ctrl2); LiteralControl __ctrl3 </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.__BuildControl__control5(); __parser.AddParsedSubObject(__ctrl3); HtmlForm __ctrl4 </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.__BuildControlform1(); __parser.AddParsedSubObject(__ctrl4); LiteralControl __ctrl5 </span>= <span style="color: #0000ff;">this</span><span style="color: #000000;">.__BuildControl__control6(); __parser.AddParsedSubObject(__ctrl5); }</span></code></pre> <br>このメソッドは、ページクラスオブジェクトをパラメータ形式で転送し、サブコントロールを個別に追加します.this._BuildControl__control6();実は後ろの3つの終了ラベル、</form></body></htmlです.前にすべてのものを作成し、ページクラスオブジェクトにも追加しましたが、この3つの終了ラベルが少なく、コードでさっきの仮説を証明しました.<pre><code><span style="color: #000000;">[DebuggerNonUserCode] </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> LiteralControl __BuildControl__control6() { LiteralControl __ctrl </span>= <span style="color: #0000ff;">new</span> LiteralControl(<span style="color: #800000;">"</span><span style="color: #800000;">\r<br/></body>\r<br/></html>\r<br/></span><span style="color: #800000;">"</span><span style="color: #000000;">); __ctrl.SetTraceData(</span><span style="color: #0000ff;">typeof</span>(TraceData), <span style="color: #0000ff;">new</span> TraceData(<span style="color: #800080;">0x2b4</span>, <span style="color: #800080;">20</span>, <span style="color: #0000ff;">true</span><span style="color: #000000;">)); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> __ctrl; }</span></code></pre> <br>Asp.NetコントロールがHTMLコードを生成する過程を記録しました.次に、サーバーがページライフサイクルを含むプロセス全体を処理すると言います.<br>  <br>