漫談ASP.NET 頁面物件模型

來源:互聯網
上載者:User
asp.net|對象|頁面 摘要:

  本文討論關於建立ASP.NET Web頁的事件模型和轉化為HTML的各個過程的細節。ASP.NET HTTP 運行時管理著把請求URL轉換成一個頁面類的具體執行個體的對象管道,接下來把這些執行個體轉換成一般的HTML文字格式設定。本文對代表各個頁面生命週期的事件、怎麼控制頁面執行、開發人員怎麼幹預這些標準行為的執行過程進行了講解。
  介紹

  每當請求IIS容納的ASP.NET頁時,總是要把請求轉交給了ASP.NET HTTP 管道。HTTP管道是一組被控對象,這些對象按順序處理請求並且把這些請求轉換成一般HTML文本。HTTP管道的入口是HttpRuntime 類。ASP.NET的底層結構為每一個應用程式定義域 ( AppDomain )的背景工作處理序建立了一個這個類(HttpRuntime)的執行個體(注意,一個背景工作處理序只能支援一個正在啟動並執行ASP.NET應用域)。

  HttpRuntime 類從內部程式池中選擇一個 HttpApplcation 對象,並且在接收到請求的時候使它工作。Http應用管理程式的主要工作是尋找這樣的類使之能夠處理請求。例如:當請求一個.aspx資源時,處理控制代碼就是一個從Page繼承類的執行個體。請求資源的類型和相關處理控制代碼的關係映射表被儲存在應用程式的設定檔裡。更確切的說,這個映射表就定義在machie.config裡的<httpHandlers>一節裡。但是,應用程式能在web.config裡對這個HTTP處理控制代碼映射列表進行重定義。下面這行語句說明了定義.aspx資源請求的處理控制代碼:

<add verb=”*” path=”*.aspx” type=”System.Web.UI.PageHandlerFactroy”/>

  一個擴充可以和一個控制代碼類聯絡起來,更一般說,是和一個控制代碼工廠類相聯絡。在所有情況下,負責處理請求的HttpApplication對象得到一個從IHttpHandler介面具體實現的對象。如果是根據HTTP控制代碼來處理資源和相關處理類的關係,則返回類是直接實現相關的介面的;如果資源是綁定到一個控制代碼工廠的話,將必須經過另外一個階段:具體實現IHttpHandlerFactory介面的控制代碼工廠類的GetHandler方法將返回一個基於IHttpHandler的對象。

  Http運行時怎麼結束一個周期或關閉一個頁面請求的進程呢?IHttpHandler介面的ProcessRequest方法擁有這個功能。調用代表被請求頁面的對象的該方法,ASP.NET底層結構開啟一個進程來為瀏覽器產生輸出。

  Page類

  一個頁面的HTTP處理控制代碼的類型取決於URL。當這個URL被首次訪問,一個新的類將被構建並動態編譯成一個程式集。一個分析aspx檔案的進程從aspx檔案中分離出這個類的代碼。在預設情況下,這個類被加入到一個叫做asp的名字空間裡,並且把URL作為這個類的類名。例如,如果請求的URL是page.aspx,則這個類就是ASP.Page_aspx。這個類名,可以通過設定@Page預先處理指令的ClassName屬性來修改。

  HTTP控制代碼的基礎類是Page類。這個類定義了一組最小方法和屬性集,這些方法和屬性被所有的頁面處理控制代碼所共用。Page類具體實現了IHttpHandler介面。

  在另外一種和上述相對應的情況中,實際處理頁面的控制代碼的基礎類並不是Page類,而是一個別的類。當使用後代碼模式時,這個情況就發生了。後代碼是一種將C#或VB.NET代碼和頁面分離的技術。頁面代碼是一組事件處理控制代碼和其他一些方法的集合,這些方法定義了頁面的各種行為。這些代碼可以以內聯形式用<script runat=server>標籤定義,或者你可以用外部類形式來寫——這就是後代碼模式。後代碼類是從Page類繼承的,但是具體化或者重新定義了一些其他的方法。在指定了頁面的後代碼類後,這個後代碼類就作為HTTP處理控制代碼。

  在其他的情況下,如果應用程式的設定檔中重定義了<pages>節的PageBaseType屬性,則HTTP處理控制代碼不是基於Page類的,例如:

<pages PageBaseType = “Classes.MyOage , mypage” />

  PageBaseType屬性指明了包含頁面處理控制代碼父類的類型和程式集。來自Page類的這些類自動賦予一些通常或擴充的方法和屬性的集合給處理控制代碼。



  頁面生命週期

  一旦HTTP頁面處理控制代碼被明確的定義了,ASP.NET運行時調用處理控制代碼的ProcessRequest方法來處理請求。通常,沒有必要改變Page類提供的執行方法。

  頁面執行是從FrameworkInitialize方法開始的,這個方法為頁面構建控制項樹。該方法是TemplageControl類的受保護並且是虛方法。任何為aspx資源動態產生的控制代碼覆蓋了該方法。在這個方法裡,頁面的所有控制項樹都被構建了。

  接下來,ProcessRequest方法使頁面經曆了不同的幾個階段:初始化、載入檢視狀態資訊、回傳資料、載入頁面代碼和執行回傳的伺服器事件。在這之後,頁面轉換到了顯示模式:收集被更新的檢視狀態;產生HTML代碼,並且傳送到控制台。最後,頁面卸載,請求的全部服務結束了。

  在各個不同階段裡,頁面處理了與web控制項相關、程式員代碼能夠幹預並解決一定問題的事件。其間一些事件是專門為那些內嵌控制項和不能在.aspx代碼層級處理的控制項而設計的。

  一個頁面要解決這樣的事件,它能明確的註冊成為合適的控制代碼。但是,為了和原有的Visual Basic編程模式有回溯相容性,ASP.NET也支援了隱含事件的形式。在預設情況下,頁面會尋找和事件相關的方法名;如果找到和事件相匹配的方法,這個方法就被認為是這種事件的處理常式。ASP.NET提供了六種專門的方法名,他們是 Page_Init , Page_Load , Page_DataBind , Page_PreRender 和 Page_Unload 。這些方法這些方法在Page類中已經被定義過,他們是相應事件的處理常式。HTTP運行時將自動的將這些方法綁定到相關的頁面事件,而不需要程式員去編寫把事件和方法聯絡起來的代碼。舉個例子來說,在下面的代碼中, Page_Load方法和頁面的載入事件相關聯:

this.Load + = new EventHandler(this.Page_Load);

  這種自動識別是被 @Page 預指令的AutoEventWireup 屬性控制的。如果這個屬性被置false ,應用程式必須顯式聲明和事件相關的方法。不自動關聯頁面事件代碼的頁面執行起來會快一些,是因為他們不需要在匹配上做過多的工作。在Visual Studio.NET 工程裡可以把這個屬性關閉掉。但是,預設設定是true,這意味著Page_Load方法被自動識別並被關聯到相關的事件。

  頁面執行包含了下表中按順序列出的幾個階段,他們被標誌成為應用程式層級的事件,同時也可能是一些受保護、重定義的方法:

階段頁面事件可重定義的方法頁面初始化Init 檢視狀態載入 LoadViewState回傳資料處理 控制項裡實現了IPostBackDataHandler介面的LoadPostData方法頁面載入Load 回傳資料變化檢查 控制項裡實現了IPostBackDataHandler介面的RaisePostDataChangedEvent方法回傳事件處理控制項裡定義的回傳事件控制項裡實現了IPostBackEventHandler介面的RaisePostBackEvent方法頁面預返回階段PreRender 頁面返回階段Render 頁面卸載階段Unload   
  上表中列出的階段有的在頁面層級是不可見的,他們只是在伺服器控制項的作者編寫繼承於Page的類時會使用到。Init , Load , PreRender , Unload,再加上定義在內嵌控制項中的回傳處理事件,他們構成了頁面的整個生命週期。

  各個階段的執行

  頁面生命週期的第一階段是初始化。這個階段被Init事件所描述,這個事件在控制項樹被構建出來後執行。換句話說,當Init事件發生時,所有在.aspx檔案中靜態聲明的控制項被執行個體化並被賦予了預設值。在Init事件中可以初始化任何的在頁面生命週期裡需要的設定。例如:在這個階段,控制項可以載入外部的摸版檔案或者是為事件建立處理控制代碼。需要注意的是,任何的檢視狀態資訊在這個階段裡是不能用的。

  緊接著初始化結束後,頁面構架為頁面載入檢視狀態。檢視狀態是 名稱/值 對的集合,控制項或頁面在這裡儲存的資料在整個web請求過程中必須是穩固的。檢視狀態代表著頁面的上下文。典型的,它儲存著頁面上次在伺服器上被執行時控制項的狀態。檢視狀態在會話開始的第一個頁面請求時是空的。在預設情況下,試圖狀態被儲存在一個隱藏欄位裡,這個隱藏欄位是被自動添加到頁面裡的。這個隱藏欄位的名稱是 __VIEWSTATE。如果覆蓋了LoadViewState方法——在Control類裡被聲明為受保護的方法——組件開發人員可以控制檢視狀態的儲存和它是如何和內部狀態形成映射。

  象LoadPageStateFormPersistenceMedium這樣的方法和與其相對應的SavePageStateToPersistenceMedium方法可以用來載入或者儲存檢視狀態到其他的儲存中介裡,例如:會話、資料庫或者是伺服器上的檔案。和LoadViewState方法不相同的是,上面提到的方法只能在Page的繼承類裡使用。

  一旦檢視狀態載入完畢了,頁面裡的控制項被賦予了和上一次發送到瀏覽器時一樣的狀態。下一個階段是將他們更新,使之與伺服器端發生的變化相一致。在回傳資料處理階段,控制項更新他們的狀態,使之和用戶端的HTML元素的狀態相一致。例如,伺服器控制項TextBox有和它相對應的HTML控制項<input type=text>。在回傳資料階段,TextBox控制項將得到<input>標籤的值,並且用他來更新他的內部狀態。每一個控制項都可以從回傳資料中取得自己資料的能力,並且把自己的狀態更新。TextBox控制項將更新它的Text屬性,同樣的,CheckBox控制項也會將他們的Checked屬性重新整理。伺服器控制項和HTML元素的匹配是通過兩者的ID來進行的。

  在回傳資料處理的最後階段,所有的頁面控制項反映了上一個被更新的狀態,這些都是由於用戶端的輸入變化所引起的。接下來,Load事件將被頁面執行。

  有一些控制項,在兩次請求中如果某些敏感屬性發生了變化,他們需要對此作出響應,並且完成一定的任務。例如,如果用戶端的textbox控制項的文本發生變化,這個控制項就激發了TextChanged事件。根據自用戶端的資料,如果控制項的一個或多個屬性發生了變化,每一個控制項都可以精確的激發合適的事件來處理。這些控制項實現了IPostBackDataHandler介面,這個介面中的LoadPostData方法在Load事件之後就被執行了。通過重定義LoadPostData方法,控制項可以驗證兩次請求中發生的變化並且激起相關的事件處理常式。

  在一個頁面周期中的關鍵事件是那些由用戶端事件激發在伺服器執行一段代碼的事件。例如,當使用者點擊一個按鈕,頁面就需要回傳。這個事件的處理是從按鈕ID和值的收集開始的。如果控制項是實現了IPostBackEventHandler介面(Button和LinkButton就是這樣的情況),頁面構架將調用RaisePostBackEvent方法。這個方法的具體情況是取決於控制項的類型的。在上面提到的Button和LinkButton控制項,這個方法就將尋找Click事件處理常式。

  處理了回傳事件之後,頁面就準備被發送出去了。這個階段是從PreRender事件開始的。這對於控制項來說,那些需要在視圖資訊被儲存與結果被發送之前這段時間裡執行的動作,這是一個很好的時機。下一步就是SaveViewState ,所有的空間和頁面本身就把檢視狀態的集合內容儲存起來。接下來,檢視狀態被序列化、雜湊編碼、Base 64 編碼,並且儲存在__VIEWSTATE隱藏欄位裡。

  各個控制項的發送機制可以通過重定義Render方法來改變。這個方法構建了一個HTML writer對象,用它來為控制項產生HTML代碼。對Page類裡Render方法的預設執行包含了對所有成員控制項的遞迴調用。頁面為每一個控制項調用一次Render方法,並緩衝HTML輸出。

  頁面生命週期的最後階段是卸載事件,這個事件在頁面對象消失前被激發。在這個事件裡,你應該把任何臨界資源釋放掉(例如:檔案、繪圖物件、資料庫連接)。

  最後,瀏覽器接收到了HTTP響應,並且把頁面顯示出來。

  總結

  ASP.NET頁面物件模型是一個有特點的新穎的模型,因為它是基於事件機制的。一個Web頁由一些控制群組成,這些控制項擁有豐富的基於HTML的使用者介面,同時通過事件和使用者進行互動。在Web應用程式上下文環境中構建一個事件模型是富有挑戰性的。使用戶端產生的事件和伺服器上的代碼關聯起來是令人驚異的,這個過程是輸出同HTML也一樣是可見的,只不過他們在需要的時候被恰當的修改。

  要瞭解頁面生命週期的各個階段、頁面對象是怎樣執行個體化並被HTTP運行時所使用,掌握這個模型是很重要的。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.