ASP.Net Web Page深入探討

來源:互聯網
上載者:User
asp.net|web 一、伺服器指令碼基礎介紹
首先,我們先複習一下Web伺服器頁面的基本執行方式:

1、 用戶端通過在瀏覽器的地址欄敲入地址來發送請求到伺服器端

2、 伺服器接收到請求之後,發給相應的伺服器端頁面(也就是指令碼)來執行,指令碼產生用戶端的響應,發送回用戶端

3、 用戶端瀏覽器接收到伺服器傳回的響應,對Html進行解析,將圖形化的網頁呈現在使用者面前


對於伺服器和用戶端的互動,通常通過下面幾種主要方式:

1、 Form:這是最主要的方式,標準化的控制項來擷取使用者的輸入,Form的提交將資料發送給伺服器端處理

2、 QueryString:通過在Url後面帶參數達到將參數傳送給伺服器,這種方式其實跟Get方式的Form是一樣的

3、 Cookies:這是一種比較特殊的方式,通常用於使用者身份的確認


二、ASP.Net簡介

傳統的伺服器指令碼語言,如ASP、JSP等,編寫伺服器指令碼的方式大同小異,都是在Html中嵌入解釋或編譯執行的代碼,由伺服器平台執行這些代碼來產生Html;對於這類似的指令碼,頁面的生存周期實際上很簡單,就是從開頭至末尾,執行完所有的代碼,當然用Java編寫的Servlet可以編寫更複雜的代碼,但是從結構上看,和JSP沒什麼區別。

ASP.Net的出現,打破了這種傳統;ASP.Net採用了CodeBehind技術和伺服器端控制項,加入了伺服器端的事件的概念,改變了指令碼語言編寫的模式,更加貼近Window編程,使Web編程更加簡單、直觀;但是我們要看到,ASP.Net本身並沒有改變Web編程的基本模式,只是封裝了一些細節、提供了一些易用的功能,使代碼更容易編寫和維護;從某種程度上來說,將伺服器端執行的方式複雜化了,這就是我們今天要討論的主體:ASP.Net Web Page的生存周期。


三、ASP.Net請求處理模式

我們說,ASP.Net的Web Page並沒有脫離Web編程的模式,所以它仍然是以 請求->接收請求->處理請求->發送響應 這樣的模式在工作,每一次與用戶端的互動都會引發一次新的請求,所以一個Web Page的生命週期是以一次請求為基礎的。

當IIS收到用戶端的請求的時候,會將請求交給aspnet_wp這個進程來處理,這個進程會查看請求的應用程式定義域是否存在,如果不存在則會建立一個,然後會建立一個Http運行時(HttpRuntime)來處理請求,這個運行時“為當前應用程式提供一組 ASP.NET 運行時服務”(摘自MSDN)。

HttpRuntime在處理請求的時候,會維護一系列的應用程式執行個體,也就是應用程式的Global類(global.asax)的執行個體,這些執行個體在沒有請求的時候,會存放在一個應用程式集區中(實際上應用程式集區由另一個類來維護,HttpRuntime只是簡單的調用),每接收到一個請求,HttpRuntime都會擷取一個閑置的執行個體來處理請求,這個執行個體在請求結束前不會處理其他的請求,處理完畢之後,它又會回到池中,“一個執行個體在其生存期內被用於處理多個請求,但它一次只能處理一個請求。”(摘自MSDN)


當應用程式執行個體處理請求的時候,它會建立請求頁面類的執行個體,執行它的ProcessRequest方法來處理請求,這個方法也就是Web Page生命週期的開始。


四、Aspx頁面與CodeBehind

在深入瞭解頁面的生命週期之前,我們先來探討一些Aspx與CodeBehind之間的關係。


<%@ Page language="c#" Codebehind="WebForm.aspx.cs" Inherits="MyNamespace.WebForm" %>


相信使用過CodeBehind技術的朋友,對ASPX頂部的這句話應該是非常熟悉了,我們來一項一項的分析它:

Page language="c#" 這個就不用多說了吧

Codebehind="WebForm.aspx.cs" 這一句表示綁定的代碼檔案

Inherits="MyNamespace.WebForm" 這句非常重要,它表示頁面繼承的類名稱,也就是CodeBehind的代碼檔案中的類,這個類必須從System.Web.WebControls.Page派生


從上面我們可以分析出,實際上CodeBehind中的類就是頁面(ASPX)的基類,到這裡,可能有些朋友要問了,在編寫ASPX的時候,完全是按照ASP的方式,在Html中內嵌程式碼或者嵌入伺服器控制項,沒有看到所謂“類”的影子啊?

這個問題實際上並不複雜,各位使用ASP.Net編程的朋友可以到你們的系統硬碟:\WINDOWS\Microsoft.NET\Framework\<版本號碼>\Temporary ASP.NET Files這個目錄下,這個下面就放了所有本機上存在的ASP.Net應用程式的臨時檔案,子目錄的名稱就是應用程式的名稱,然後再下去兩層(為了保證唯一,ASP.Net自動產生了兩層子目錄,並且子目錄名稱是隨機的),然後我們會發現有很多類似:“yfy1gjhc.dll”、“xeunj5u3.dll”這樣的連結庫以及“komee-bp.0.cs”、“9falckav.0.cs”這樣的源檔案,實際上這就是ASPX被ASP.Net動態編譯後的結果,開啟這些源檔案我們可以發現:

public class WebForm_aspx : MyNamespace.WebForm, System.Web.SessionState.IRequiresSessionState


這就印證了我們前面的說法,ASPX是代碼綁定類的子類,它的名稱是ASPX檔案名稱加上“_aspx”尾碼,通過研究這些代碼我們可以發現,實際上所有aspx中定義的伺服器控制項都是在這些代碼中產生的,然後動態產生這些代碼的時候,把原來在ASPX中嵌入的代碼寫在了相應的位置。

當某個頁面第一次被訪問的時候,Http運行時就會使用一個代碼產生器去解析ASPX檔案並產生原始碼並編譯,然後以後的訪問就直接調用編譯後的dll,這也是為什麼ASPX第一次訪問的時候非常慢的原因。



解釋了這個問題,我們再來看另一個問題。我們在使用代碼綁定的時候,在設計頁面拖一個控制項,然後切換到程式碼檢視,就可以直接在Page_Load中使用這個控制項了,既然控制項是在子類中產生的,那為什麼在父類中可以直接使用呢?

實際上我們可以發現,每當用VS.Net拖一個控制項到頁面上,代碼繫結檔案中總是會類似這樣的添加一個聲明:

protected System.Web.WebControls.Button Button1;


我們可以發現這個欄位被聲明成protected,而且名字與ASPX中控制項的ID一致,仔細想一想,這個問題就迎刃而解了。我們前面提到ASPX的原始碼是被產生器動態產生和編譯的,產生器會產生動態產生每一個伺服器控制項的代碼,在產生的時候,它會檢查父類有沒有聲明這個控制項,如果聲明了,它會添加類似下面的一句代碼:

this.DataGrid1 = __ctrl;


這個__ctrl就是產生該控制項的變數,這時候它就把控制項的引用賦給了父類中相應的變數,這也是為什麼父類中的聲明必須為protected(實際上也可以為public),因為要保證子類能夠調用。

然後在執行Page_Load的時候,因為這時候父類的聲明已經被子類中的初始化代碼賦了值,所以我們就可以使用這個欄位來訪問對應的控制項,瞭解了這些,我們就不會犯在代碼繫結檔案中的構造器裡使用控制項,造成Null 參考的異常的錯誤了,因為構造器是最先執行的,這時候子類的初始化還沒有開始,所以父類中的欄位是空值,至於子類是什麼時候初始化我們放到後面討論。

五、頁面生存周期

現在回到第三個標題中講到的內容,我們講到了HttpApplication的執行個體接收請求,並建立頁面類的執行個體,實際上這個執行個體也就是動態編譯的ASPX的類的一個執行個體,上一個標題中我們瞭解到ASPX實際上是代碼綁定中類的子類,所以它繼承了所有的protected方法。

現在我們來看看VS.Net自動產生的CodeBehind類的代碼,以此來開始我們對頁面生命週期的探討:

#region Web Form Designer generated code

override protected void OnInit(EventArgs e)

{

//

// CODEGEN:該調用是 ASP.NET Web Form設計器所必需的。

//

InitializeComponent();

base.OnInit(e);

}


/// <summary>

/// 設計器支援所需的方法 - 不要使用代碼編輯器修改

/// 此方法的內容。

/// </summary>

private void InitializeComponent()

{

this.DataGrid1.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid1_ItemDataBound);

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


}

#endregion

這個就是使用VS.Net產生的Page的代碼,我們來看,這裡面有兩個方法,一個是OnInit,一個是InitializeComponent,後者被前者調用,實際上



相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.