Application
The ASP.NET Application Life Cycle
1. 送出請求
應用程式生命週期啟始於使用者提出網頁需求(page request)。
2. 將請求交由處理管道(Process Pipeline)
將請求導進入Process Pipeline(一種程序管道),再交由 runtime 處理。
- 在IIS 5.0以及6.0以及7.0的傳統模式
這個模式下的 ASP.NET 要求管線會與 Web 伺服器管線分開。 當 Web 伺服器收到要求時,會檢查要求檔案的副檔名、判斷應該處理要求的 ISAPI 擴充程式,然後將要求傳遞至適當的 ISAPI 擴充程式。 ASP.NET 只會處理已對應的副檔名,例如 .aspx、.ascx、.ashx 和 .asmx。 若是其它資料檔 .jpg 或 .htm 檔,通常不會對應至 ASP.NET,所以 ASP.NET 不會對 .htm 檔執行驗證或授權檢查。 - IIS 7.0的整合模式
這個模式中只有一個通用的管道來處理所有應用程式內的資源請求,這使得資料檔或aspx網頁都可以用相同的管道來處理。
3. 建立 ApplicationManager 實體
runtime 會為每個使用者建立一個 ApplicationManager 實體,用來執行應用程式的 AppDomain 環境,每個 AppDomain 都是獨立的,彼此隔離,以免全域變數互相存取。
4. 建立 HostingEnvironment 實體
在 AppDomain 被建立之後,會再建立一個 HostingEnvironment 實體,用來存取主機內的資源,如檔案目錄。
5. 建立核心物件
這個階段,ASP.NET 會產生處理請求的核心物件(core object),如: HttpContext 、 HttpRequest 、 HttpResponse 。
6. 建立 HttpApplication 實體
ASP.NET 建立一個 HttpApplication 實體(或是重複使用已建立實體),用來追縱 appliction 的事件。 在建立 HttpApplication 同時,也會建立適當的 modules ,對需求進行額外的事件處理,如 FormsAuthenticationModule 、 UrlRoutingModule 。
(這個步驟在網站啟動後只會在首次遇到需求時被執行一次,它是 Global.asax 的基底類別)
7. 交由 HttpApplication 負責處理
最後,所有請求都會被送進 HttpApplication 管道處理。 這個管道包含各種處理模組,如 validating requests, mapping URLs, accessing cache 等。
The Application Events
1. Application_Start
這個事件通常是因為初次請求應用程式頁面時,被IIS所觸發。
在這個事件中可以初始化Application層級的變數
2. Application_End
這個事件通常都是在應用程式被關閉(Shutdown),通常可以釋放資源,或是記錄特定事件(Log)
3. Application_Error
這個事件是在非預期的例外事件產生,並被拋到應用程式層級,我們可以在這裡進行應用程式最壞狀況的處理,例如進行Log。
4. Application_LogRequest
這個機制是當應用程式接到請求的時候,都會被觸發。
5. Application_PostLogRequest
當完成請求後會被觸發。
其他的 Application_ 事件,請參考MSDN http://support.microsoft.com/kb/312607
- Application_Init:在應用程式被實例化或第一次被調用時,該事件被觸發。對於所有的HttpApplication物件實例,它都會被調用。
- Application_Disposed:在應用程式被銷毀之前觸發。這是清除以前所用資源的理想位置。
- Application_Error:當應用程式中遇到一個未處理的異常時,該事件被觸發。
- Application_Start:在HttpApplication 類的第一個實例被創建時,該事件被觸發。它允許你創建可以由所有HttpApplication 實例訪問的物件。
- Application_End:在HttpApplication 類的最後一個實例被銷毀時,該事件被觸發。在一個應用程式的生命週期內它只被觸發一次。
- Application_BeginRequest:在接收到一個應用程式請求時觸發。對於一個請求來說,它是第一個被觸發的事件,請求一般是用戶輸入的一個頁面請求(URL)。
- Application_EndRequest:針對應用程式請求的最後一個事件。
- Application_PreRequestHandlerExecute:在 ASP.NET 頁面框架開始執行諸如頁面或 Web 服務之類的事件處理程式之前,該事件被觸發。
- Application_PostRequestHandlerExecute:在 ASP.NET 頁面框架結束執行一個事件處理程式時,該事件被觸發。
- Applcation_PreSendRequestHeaders:在 ASP.NET 頁面框架發送 HTTP 頭給請求客戶(流覽器)時,該事件被觸發。
- Application_PreSendContent:在 ASP.NET 頁面框架發送內容給請求客戶(流覽器)時,該事件被觸發。
- Application_AcquireRequestState:在 ASP.NET 頁面框架得到與當前請求相關的當前狀態(Session 狀態)時,該事件被觸發。
- Application_ReleaseRequestState:在 ASP.NET 頁面框架執行完所有的事件處理程式時,該事件被觸發。這將導致所有的狀態模組保存它們當前的狀態資料。
- Application_ResolveRequestCache:在 ASP.NET 頁面框架完成一個授權請求時,該事件被觸發。它允許緩存模組從緩存中為請求提供服務,從而繞過事件處理程式的執行。
- Application_UpdateRequestCache:在 ASP.NET 頁面框架完成事件處理程式的執行時,該事件被觸發,從而使緩存模組存儲回應資料,以供回應後續的請求時使用。
- Application_AuthenticateRequest:在安全模組建立起當前用戶的有效的身份時,該事件被觸發。在這個時候,用戶的憑據將會被驗證。
- Application_AuthorizeRequest:當安全模組確認一個用戶可以訪問資源之後,該事件被觸發。
- Session_Start:在一個新用戶訪問應用程式 Web 站點時,該事件被觸發。
- Session_End:在一個用戶的會話超時、結束或他們離開應用程式 Web 站點時,該事件被觸發。
Webpage
ASP.NET 頁面事件的執行順序
PreInit
這個階段用來進行物件初始化,例如: MasterPage, Theme, 動態產生控制項。
PreLoad
ViewState 會在這個階段前載入,所以必須在這個階段才讀取的到。 所以若你要變更 ViewState ,至少要在這個階段之後。
Load
這個階段初始化以及ViewState(控件的狀態)都會被建立完成。 Load事件是由Page的Load最先執行,再執行其下的控件的Load事件。
Control Event
這個事件是 PostBack 後才會執行。緊跟著 Page_Load 之後。
PreRender
ViewState 會在這個階段前儲存,所以必須在這個階段才讀取的變更後的值。
Render
在這個階段可以撰寫一些我們的自訂控件的需求。
ViewState 與 Page 事件的順序
在 WebPage 的生命週期中,會有二個事件用來讀取和寫入 ViewState 。
- LoadViewState :Restores view-state information from a previous page request that was saved by the SaveViewState method.
- SaveViewState :Saves any server control view-state changes that have occurred since the time the page was posted back to the server.
所以若要變更 ViewState ,必須在 Page_PreLoad 之後。 另外,你可能利用 postback 事件去更改 ViewState 值,所以若你想利用 ViewState 值,以管理控制項狀態,通常會在 Page_PreRender 執行。
Controls
動態加入控制項
若要在執行階段,動態加入控制項,如果沒有使用 MasterPage ,可以在 Page_PreInit 事件中。 若有用 MasterPage ,則必須在 Page_Init 事件中。
由於 Theme 在 Page_PreInit 就載入結束,所以如果你在 Page_Init 事件才加入控制項,就必須自行呼叫 Control.ApplyStyleSheetSkin 方法,以套用樣式。
protected void Page_PreInit(object sender, EventArgs e) { btnTestButton1.Text = "Test Button 1"; btnTestButton1.Click += btnTestButton1_Click; Literal1.Text = "<br>"; PlaceHolder1.Controls.Add(Literal1); btnTestButton2.Text = "Test Button 2"; PlaceHolder1.Controls.Add(btnTestButton1); PlaceHolder1.Controls.Add(btnTestButton2); } protected void Page_Load(object sender, EventArgs e) { //若在 Page_Init 才載入控制項,則必須手動套用樣板 btnTestButton1.ApplyStyleSheetSkin(this); } public void btnTestButton1_Click(object sender, EventArgs e) { myMessage.Show(this, "Test Button 1 Click"); }
控制項事件的執行順序
所有的控制項和 Page 都是繼承自 Control 物件,所以都使用相同的生命週期。 例如:當 Page 發生 Load 事件,則會相繼發生其子控制項的 Load 事件。
另外,要注意動態載入的控制項,其事件順序就得看它的實體何被建立的。
另外,若在 Page_Render 中才執行動態加入控制項,就無效了。
沒有留言:
張貼留言