1. 程式人生 > >【譯】ASP.NET應用程式和頁面生命週期

【譯】ASP.NET應用程式和頁面生命週期

  • 概述
  • 大體上的兩步處理流程
  • ASP.NET環境的建立
  • 通過MHPM觸發的事件處理請求
  • 在什麼事件中我們可以做什麼?
  • 一個簡單的示例
  • 詳解ASP.NET頁面事件

  圖2 ASP.NET環境的建立

  下圖則形象地展示了在一個ASP.NET請求過程中的重要內部物件模型。最高層是ASP.NET執行時,它建立了一個應用程式域(AppDoamin),下層則建立了一個包含request、response以及context物件的HttpRuntime。

General Explain Steps

 圖3 ASP.NET請求過程中的內部物件模型

四、通過MHPM觸發的事件處理請求

  一旦HttpApplication建立好,它就開始處理請求了。它經歷了三個不同的部分:HttpModulePageHttpHandler。當它經過這些部分時,它將呼叫不同的事件,而這些事件的邏輯處理還可以由開發者來進行擴充套件和增加自定義處理。

  在進一步深入瞭解之前,讓我們先來了解一下什麼是HttpModuleHttpHandlers。他們幫助我們在ASP.NET頁面處理過程的前後注入自定義的邏輯處理。他們之間主要的差別在於:

  • 如果你想要注入的邏輯是基於像'.aspx','.html'這樣的副檔名,那麼你可以使用HttpHandler
    。換句話說,HttpHandler是一個基於處理器的擴充套件。

HttpHandler Show

圖4 HttpHandler

  • 如果你想要在ASP.NET管道事件中注入邏輯,那麼你可以使用HttpModule。也可以說,HttpModule是一個基於處理器的事件。

HttpModule Show

圖5 HttpModule

  你可以從這裡瞭解更多關於他們這對好基友之間的差別。

  下面是請求處理過程的邏輯流程,其中有4個重要的步湊,解釋如下:

  第一步(M:HttpModule):客戶端請求開始被處理。在ASP.NET引擎執行和建立HttpModule

觸發事件(在此過程中,你也可以注入自定義邏輯)之前,有6個事件你可以在頁面物件建立之前來使用,它們分別是:BeginRequestAuthenticateRequestAuthorizeRequestResolveRequestCacheAcquireRequestState 以及 PreRequestHandlerExecute

  第二步(H:HttpHandler):一旦以上6個事件被觸發後,ASP.NET引擎就將會呼叫 ProcessRequest 事件,即使你已經在專案中實現了 HttpHandler

  第三步(P:ASP.NET Page):一旦HttpHandler邏輯執行,ASP.NET頁面物件就被建立了。而ASP.NET頁面被建立,一系列的事件也會隨之被觸發,它們可以幫助我們自定義邏輯注入到這些事件裡邊。在此過程中,有6個重要事件給我們提供了佔位符,以便我們在ASP.NET頁面中寫入邏輯,它們分別是:InitLoadValidateRender Unload。你可以通過記住單詞SILVER來記憶這幾個事件,S—Start(沒有任何意義,僅僅是為了形成一個單詞),I(Init)、L(Load)、V(Validate)、E(Event)、R(Render)。

  第四步(M:HttpModule):一旦頁面物件執行結束並從記憶體中被解除安裝,HttpModule提供了提交返回頁面的執行事件,同樣,在這些事件中也可以被注入自定義的返回處理邏輯。這裡有4個重要的提交處理事件:PostRequestHandlerExecuteReleaserequestStateUpdateRequestCache以及EndRequest

  下圖形象地展示了上面的四個步湊。

MHPM

圖6 MHPM過程

五、在什麼事件中我們可以做什麼?

  一個十分有價值的問題就是在什麼事件中我們又可以做些什麼?下表就展示了這個問題的答案:

Section Event Description
HttpModule BeginRequest 此事件標誌著一個新的請求,它保證在每個請求中都會被觸發。
HttpModule AuthenticateRequest 此事件標誌ASP.NET執行時準備驗證使用者。任何身份驗證程式碼都可以在此注入。
HttpModule AuthorizeRequest 此事件標誌ASP.NET執行時準備授權使用者。任何授權程式碼都可以在此注入。
HttpModule ResolveRequest 在ASP.NET中我們通常使用OutputCache指令做快取。在這個事件中,ASP.NET執行時確定是否能夠從快取中載入頁面,而不是從頭開始生成。任何快取的具體活動可以被注入這裡。
HttpModule AcquireRequestState 此事件標誌著ASP.NET執行時準備獲得Session會話變數。可以對Session變數做任何你想要做的處理。
HttpModule PreRequestHandlerExecute 恰好在ASP.NET 開始執行事件處理程式前發生。可以預處理你想做的事。
HttpHandler ProcessRequest HttpHandler邏輯被執行。在這個部分我們將為每個頁面擴充套件寫需要的邏輯。
Page Init 此事件發生在ASP.NET頁面且可以用來: 
1、動態地建立控制元件,如果你一定要在執行時建立控制元件; 
2、任何初始化設定 
3、母版頁及其設定 
在這部分中我們沒有獲得viewstate、postedvalues及已經初始化的控制元件。
Page Load 在這部分ASP.NET控制元件完全被載入且在這裡你可以寫UI操作邏輯或任何其他邏輯。NOTE:這個事件也是我們最常見且最常用的一個事件。
Page Validate 如果在頁面上你有驗證器,你同樣想在這裡做一下檢查。
Page Render 是時候將輸出傳送到瀏覽器。如果你想對最終的HTML做些修改,你可以在這裡輸入你的HTML邏輯。
Page Unload 頁面物件從記憶體中解除安裝。
HttpModule PostRequestHandlerExecute 可以注入任何你想要的邏輯,在處理程式執行之後。
HttpModule ReleaseRequestState 如果你想要儲存對某些狀態變數的更改,例如:Session變數的值。
HttpModule UpdateRequestCache 在結束之前,你是否想要更新你的快取。
HttpModule EndRequest 這是將輸出傳送到客戶端瀏覽器之前的最後一個階段。

六、一個簡單的示例

  我們可以通過一個示例程式程式碼來展示以上介紹的那些事件是怎樣被最終觸發的。在這個示例中,我們已經建立了一個HttpModuleHttpHandler,並且也在所有的事件中通過新增自定義邏輯程式碼展示了一個簡單的響應。

  下面是HttpModule類,它跟蹤了所有的事件並將其新增到了一個全域性的集合中。

public class clsHttpModule : IHttpModule
{
...... 
void OnUpdateRequestCache(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnUpdateRequestCache");
}
void OnReleaseRequestState(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnReleaseRequestState");
}
void OnPostRequestHandlerExecute(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnPostRequestHandlerExecute");
}
void OnPreRequestHandlerExecute(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnPreRequestHandlerExecute");
}
void OnAcquireRequestState(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnAcquireRequestState");
}
void OnResolveRequestCache(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnResolveRequestCache");
}
void OnAuthorization(object sender, EventArgs a)
{
objArrayList.Add("httpModule:OnAuthorization");
}
void OnAuthentication(object sender, EventArgs a)
{

objArrayList.Add("httpModule:AuthenticateRequest");
}
void OnBeginrequest(object sender, EventArgs a)
{

objArrayList.Add("httpModule:BeginRequest");
}
void OnEndRequest(object sender, EventArgs a)
{
objArrayList.Add("httpModule:EndRequest");
objArrayList.Add("<hr>");
foreach (string str in objArrayList)
{
httpApp.Context.Response.Write(str + "<br>") ;
}
} 
}
View Code

  下面是HttpHandler類的一個程式碼片段,它跟蹤了ProcessRequest事件。

public class clsHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
clsHttpModule.objArrayList.Add("HttpHandler:ProcessRequest");
context.Response.Redirect("Default.aspx");
}
}
View Code

  同上,我們也可以跟蹤來自ASP.NET Page頁面的所有事件。

public partial class _Default : System.Web.UI.Page 
{
protected void Page_init(object sender, EventArgs e)
{

clsHttpModule.objArrayList.Add("Page:Init");
}
protected void Page_Load(object sender, EventArgs e)
{
clsHttpModule.objArrayList.Add("Page:Load");
}
public override void Validate() 
{
clsHttpModule.objArrayList.Add("Page:Validate");
}
protected void Button1_Click(object sender, EventArgs e)
{
clsHttpModule.objArrayList.Add("Page:Event");
}
protected override void Render(HtmlTextWriter output) 
{
clsHttpModule.objArrayList.Add("Page:Render");
base.Render(output);
}
protected void Page_Unload(object sender, EventArgs e)
{
clsHttpModule.objArrayList.Add("Page:UnLoad");
}
}
View Code

  下圖則顯示了上面我們所討論的所有事件的執行順序。

A Sample Demo

圖7 示例結果—事件的執行次序

七、詳解ASP.NET頁面事件

  在上面的部分中,我們已經瞭解了一個ASP.NET頁面請求事件的整體流程。那麼,在其中一個最重要的部分就是ASP.NET頁面,但是我們並沒有對其進行詳細討論。因此,我們在此深入地瞭解一下ASP.NET頁面事件。

  每一個ASP.NET頁都有2個部分:一個是在瀏覽器中進行顯示的部分,它包含了HTML標籤、viewstate形式的隱藏域 以及 在HTML input中的資料。當這個頁面被提交到伺服器時,這些HTML標籤會被建立到ASP.NET控制元件,並且viewstate還會和表單資料繫結在一起。一旦你在後置程式碼中得到所有的伺服器控制元件,你可以執行和寫入你自己的邏輯並呈現給客戶瀏覽器。

ASP.NET Page

圖8 ASP.NET頁的兩個部分

  現在這些HTML控制元件會作為ASP.NET控制元件存活在伺服器上,ASP.NET會觸發一系列的事件,我們也可以在這些事件中注入自定義邏輯程式碼。根據你想要執行什麼樣的任務/邏輯,我們需要將邏輯合理地放入這些事件之中。

  注意:大部分的開發者直接使用Page_Load來幹所有的事情,但這並不是一個好的思路。因此,無論是填充控制元件、設定ViewState還是應用主題等所有發生在頁面載入中的所有事情。因此,如果我們能夠在合適的事件中放入邏輯,那麼毫無疑問我們程式碼將會乾淨很多。  

順序 事件名稱 控制元件初始化 ViewState可用 表單資料可用 什麼邏輯可以寫在這裡?
1 Init No No No 注意:你可以通過使用ASP.NET請求物件訪問表單資料等,但不是通過伺服器控制元件。
動態地建立控制元件,如果你一定要在執行時建立;任何初始化設定;母版頁及其設定。在這部分中我們沒有獲得viewstate、提交的資料值及已經初始化的控制元件。
2 Load View State Not guaranteed Yes Not guaranteed 你可以訪問View State及任何同步邏輯,你希望viewstate被推到後臺程式碼變數可以在這裡完成。
3 PostBackdata Not guaranteed Yes Yes 你可以訪問表單資料。任何邏輯,你希望表單資料被推到後臺程式碼變數可以在這裡完成。
4 Load Yes Yes Yes 在這裡你可以放入任何你想操作控制元件的邏輯,如從資料庫填充combox、對grid中的資料排序等。這個事件,我們可以訪問所有控制元件、viewstate、他們傳送過來的值。
5 Validate Yes Yes Yes 如果你的頁面有驗證器或者你想為你的頁面執行驗證,那就在這裡做吧。
6 Event Yes Yes Yes

如果這是通過點選按鈕或下拉列表的改變的一個回發,相關的事件將被觸發。與事件相關的任何邏輯都可以在這裡執行。

PS:這個事件想必很多使用WebForm的開發人員都很常用吧,是否記得那些Button1_Click(Object sender,EventArgs e)?

7 Pre-render Yes Yes Yes 如果你想對UI物件做最終的修改,如改變屬性結構或屬性值,在這些控制元件儲存到ViewState之前。
8 Save ViewState Yes Yes Yes 一旦對伺服器控制元件的所有修改完成,將會儲存控制元件資料到View State中。
9 Render Yes Yes Yes 如果你想新增一些自定義HTML到輸出,可以在這裡完成。
10 Unload Yes Yes Yes 任何你想做的清理工作都可以在這裡執行。

Page Events in Detail

圖9 ASP.NET Page事件流程

一張圖複習ASP.NET請求處理(自己補充,非原文內容)

翻譯中參考的資料 

譯者:周旭龍

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。

相關推薦

ASP.NET應用程式頁面生命週期

概述 大體上的兩步處理流程 ASP.NET環境的建立 通過MHPM觸發的事件處理請求 在什麼事件中我們可以做什麼? 一個簡單的示例 詳解ASP.NET頁面事件

ASP.NET Core在 .NET Core 3.1 Preview 1中的更新

.NET Core 3.1 Preview 1現在可用。此版本主要側重於錯誤修復,但同時也包含一些新功能。 這是此版本的ASP.NET Core的新增功能: 對Razor components的部分類支援 將引數傳遞給頂級元件 在HttpSysServer中支援共享佇列 在SameSite cookies的

ASP.NET Core updates in .NET 5 Preview 8

  .NET 5 預覽版 8 現在已經可以獲取了,並且已經準備好接受評估。下面列出了本次釋出的新特性: 使用 Microsoft.Identity.Web 進行 Azure Active Directory 認證 Blazorz 元件的 CSS 隔離 Blazor WebAssem

Asp.net Ajax 客戶端頁面生命週期原生事件

init Event [初始化事件]    在所有指令碼被載入後,在任何一個物件被建立之前引發該事件。如果你打算寫一個元件(指令碼),init 事件提供了一個在生命週期內新增元件(指令碼)到頁面的點。該元件可以被其它在生命週期內的指令碼呼叫。如果你是一個網頁開發人員,在大多數

ASP.NET最常用的頁面生命週期事件

PreInit:在頁生命週期的早期階段可以訪問的事件。在PreInit事件後,將載入個性化資訊和頁主題。 Init:在所有的控制元件都已初始化,且已應用所有外觀設定後引發。使用該事件來讀取或初始化控制元件屬性。 InitComplete:在頁初始化完成時發生。 Pr

bc信用盤源碼出售ASP.NET應用程序

output 之一 處理流 pen asp.net internet asps ofo 類型 bc信用盤源碼出售 Q1446595067 TeeChart通過WebChart TeeChart Control 集成用於WebForms,可以在標準TeeChart.NET

轉載ASP.NET 固定GridView的表頭某幾列

原連結: 固定GridView的表頭和某幾列 原文連結有個Demo程式碼,如果有需要的話可以點選原文再下載。 原來系統中有很多超長gridview,需要使用者向右平行拉動才能看到後面的內容。目前開發一

4Asp.Net Core2.2中間件多擴展對應應用

text mic 之前 nbsp 成了 配置 cor 形式 固定 【前言】 上一篇完成了Asp.Net Core 2.2全新的管道處理模型解析,“俄羅斯套娃”式的委托嵌套和傳遞,組建了擴展性無與倫比的管道模型!與此同時,委托嵌套過於復雜,使用起來並

記錄ASP.NET MVC View 移動版瀏覽的奇怪問題

手機瀏覽器 超鏈接 jquery 記錄 元素 ASP.NET MVC View 中的一段代碼:<span id="span_Id">@Model.ID</span>沒什麽問題吧,瀏覽器瀏覽正常,查看元素為:<span id="span_Id">12345

ASP.NET Core API 版本控制

新的 你們 rabl api ref add read .net b- 幾天前,我和我的朋友們使用 ASP.NET Core 開發了一個API ,使用的是GET方式,將一些數據返回到客戶端 APP。我們在前端進行了分頁,意味著我們將所有數據發送給客戶端,然後進行一些data

翻譯ASP.NET Core 文檔目錄

www asp nbsp .com col actions size 組件 ons 簡介 入門 創建一個Web應用程序 創建一個Web API 教程 基礎 MVC Razor Pages Razor 語法 Model 綁定

轉載ASP.NET Core 依賴註入

microsoft 銷毀 分享圖片 ros inview 我們 col info 服務 本文轉自:http://www.jessetalk.cn/2017/11/06/di-in-aspnetcore/ 為什麽要寫這個博客 DI在.NET Core裏面被提到了一個非常重

ASP.NET Core 依賴註入

接口 provide ddt 應該 ML 大型 RF zid yui DI在.NET Core裏面被提到了一個非常重要的位置, 這篇文章主要再給大家普及一下關於依賴註入的概念,身邊有工作六七年的同事還個東西搞不清楚。另外再介紹一下.NET Core的DI實現以及對實例生命

Asp.net 用datalist嵌套的方法實現二級菜單的分類導航

col ESS 方法 tab server select lec cut esp 剛開始學習Asp.net做網站的時候, 做的是一個電子圖書購買網站,發現圖書有多級類目。 例如:小說分類下面世界名著,中國古典小說....... 文學類目下有

ASP.NET Core開發之HttpContext

tde ont req build tro use 如何使用 ram web ASP.NET Core中的HttpContext開發,在ASP.NET開發中我們總是會經常用到HttpContext。 那麽在ASP.NET Core中要如何使用HttpContext呢,下面

微軟出品HashiCorp Terraform Vault 系列視頻

end 增長 extend 活動 provide ora azure 進步 工程 自從宣布與 HashiCorp 的多年合作以來, 微軟已經取得了長足的進步, 以確保 HashiCorp 工具在 Azure 的公共雲產品上作為頭等艙的公民運作。通過 Microsoft 和

理解 Javascript 執行上下文執行棧

原文地址:Understanding Execution Context and Execution Stack in Javascript 譯文地址:理解 Javascript 執行上下文和執行棧 譯者:夏佳昊 校對

原創Windows上應用程式報錯常用分析方法總結

在日常使用Windows的過程中,經常會遇到應用程式不能正常啟動、關閉等使用問題。對於Windows來說,解決這些問題的方法比較多,大多時候我們可以通過百度或谷歌搜尋來解決。但更多的時候,我們需要找出背後的原因,也要掌握分析問題和解決問題的方法。 分析應用程式異常的問題,一般的出發點有兩個,第一從應用程式本

IIS 7.0 的 ASP.NET 應用程式生命週期概述

    文章:IIS 7.0 的 ASP.NET 應用程式生命週期概述 地址:https://msdn.microsoft.com/zh-cn/library/bb470252(v=vs.100).aspx 本主題介紹在 IIS 7.0 整合模式下執行以及與 IIS 7.0 或更高

Javascript: call()、apply() bind()

原文地址:Javascript: call(), apply() and bind() 原文作者:Omer Goldberg 譯文出自:掘金翻譯計劃 本文永久連結:github.com/xitu/gold-m… 譯者:YueYong 校對者:Guangping, s