您好,登錄后才能下訂單哦!
怎樣看待ASP.NET應用程序與頁面生命周期,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
我們將了解不同的事件,ASP.NET 應用程序的生命周期以瀏覽器向 Web 服務器(對于 ASP.NET 應用程序,通常為 IIS)發送請求為起點,直至將請求結果返回至瀏覽器結束。在這個過程中,首先我們需要了解ASP.NET請求的2個大致的步驟。其次我們將詳細了解 'httphandler ',' httpmodule和 asp.net 頁面對象(Page)中不同的事件的執行順序,邏輯。
二個步驟的過程:
asp.net請求處理,2步的過程如下所示,用戶發送一個請求到IIS 服務器:
1、asp.net創建一個運行時,可以處理請求。換句話說,它創建應用程序對象,請求,響應和上下文對象處理請求。
2、運行時一旦被創建,請求處理,通過一系列的事件處理模塊,Handler處理和頁面對象。簡稱MHPM (Module, handler, page and Module event)。
ASP.NET 應用程序生命周期的各個階段:
步驟1:用戶從 Web 服務器請求應用程序資源 ASP.NET 應用程序的生命周期以瀏覽器向 Web 服務器(對于 ASP.NET 應用程序,通常為 IIS)發送請求為起點。ASP.NET 是 Web 服務器下的 ISAPI 擴展。Web 服務器接收到請求時,會對所請求的文件的文件擴展名進行檢查,確定應由哪個 ISAPI 擴展處理該請求,然后將該請求傳遞給合適的 ISAPI 擴展。ASP.NET 處理已映射到其上的文件擴展名,如 .aspx、.ascx、.ashx 和 .asmx。
步驟2:ASP.NET 接收對應用程序的***個請求 當 ASP.NET 接收到對應用程序中任何資源的***個請求時,名為 ApplicationManager 的類會創建一個應用程序域。應用程序域為全局變量提供應用程序隔離,并允許單獨卸載每個應用程序。在應用程序域中,將為名為 HostingEnvironment 的類創建一個實例,該實例提供對有關應用程序的信息(如存儲該應用程序的文件夾的名稱)的訪問。
步驟3:為每個請求創建 ASP.NET 核心對象 創建了應用程序域并對 HostingEnvironment 對象進行了實例化之后,ASP.NET 將創建并初始化核心對象,如 HttpContext、HttpRequest 和 HttpResponse。HttpContext 類包含特定于當前應用程序請求的對象,如 HttpRequest 和 HttpResponse 對象。HttpRequest 對象包含有關當前請求的信息,包括 Cookie 和瀏覽器信息。HttpResponse 對象包含發送到客戶端的響應,包括所有呈現的輸出和 Cookie。
步驟4:將 HttpApplication 對象分配給請求初始化所有核心應用程序對象之后,將通過創建 HttpApplication 類的實例啟動應用程序。如果應用程序具有 Global.asax 文件,則 ASP.NET 會創建 Global.asax 類(從 HttpApplication 類派生)的一個實例,并使用該派生類表示應用程序。
注:***次在應用程序中請求 ASP.NET 頁或進程時,將創建 HttpApplication 的一個新實例。不過,為了盡可能提高性能,可對多個請求重復使用 HttpApplication 實例。
步驟5: 由 HttpApplication 管線處理請求 MHPM (Module, handler, page and Module event)。
使用MHPM (Module, handler, page and Module event) 事件處理請求
一旦 HttpApplication對象創建,在處理該請求時將由 HttpApplication 類執行。我們來了解下HttpModule HttpHandlers。
1、如果你想通過*.aspx,*.html文件來處理程序邏輯,那么你需要使用HttpHandler,換句話說,httphandler是一個擴展的處理器。
2、如果你想使用ASP.NET管道來處理程序邏輯,你需要使用HttpModule 換句話說,httpmodule是一個事件處理器。
如何處理請求。mhpm有4個重要的步驟:
步驟1(M: HttpModule):客戶端開始請求處理。在asp.net引擎和httpmodule中的事件可以用來處理用戶自己定義的邏輯。有6個重要的事件,你可以在你的頁面對象被創建之前調用 Begin Request,authenticaterequest,authorizerequest,resolverequestcache,acquirerequeststate與prerequesthandlerexecute。
步驟2(H: ‘HttpHandler’):一旦上述6個事件被執行完,asp.net引擎調用processrequest事件,如果已實現httphandler在您的項目。
步驟3(P: ASP.NET page):一旦httphandler執行,asp.net頁面對象被創建。而asp.net頁面對象被創建,Page對象的事件將被調用,這可以幫助我們頁面中定制自定義邏輯的處理。有6個重要的事件,Init, Load, validate, event, render ,unload 簡稱 SILVER S – Start (does not signify anything as such just forms the word) , I – (Init) , L (Load) , V (Validate), E (Event) and R (Render)。
步驟4(M: HttpModule):一旦頁面對象是執行和從內存中卸載,httpmodule提供網頁執行事件可以用來注入自定義處理邏輯。有4個重要的后處理事件postrequesthandlerexecute,releaserequeststate,updaterequestcache與endrequest。
事件詳細介紹:
部分 | Event事件 | Description描述 |
HttpModule | BeginRequest | 在 ASP.NET 響應請求時作為 HTTP 執行管線鏈中的***個事件發生。BeginRequest 事件發出信號表示創建任何給定的新請求。此事件始終被引發,并且始終是請求處理期間發生的***個事件。 |
HttpModule | AuthenticateRequest | 當安全模塊已建立用戶標識時發生。AuthenticateRequest 事件發出信號表示配置的身份驗證機制已對當前請求進行了身份驗證。 |
HttpModule | AuthorizeRequest | 安全模塊已驗證用戶授權時發生。AuthorizeRequest 事件發出信號表示 ASP.NET 已對當前請求進行了授權。 |
HttpModule | ResolveRequestCache | 在 ASP.NET 完成授權事件以使緩存模塊從緩存中為請求提供服務后發生,從而繞過事件處理程序(例如某個頁或 XML Web services)的執行。 |
HttpModule | AcquireRequestState | 當 ASP.NET 獲取與當前請求關聯的當前狀態(如會話狀態)時發生。AcquireRequestState 事件在創建了事件處理程序之后引發。 |
HttpModule | PreRequestHandlerExecute | 恰好在 ASP.NET 開始執行事件處理程序(例如,某頁或某個 XML Web services)前發生。 |
HttpHandler | ProcessRequest | Httphandler邏輯被執行。 在本節中,我們會寫,需要將每頁擴展執行的邏輯。 |
Page | Init | OnInit 方法執行創建 Page 實例所需的初始化和設置步驟。在頁生命周期的此階段中,頁中聲明的服務器控件都已初始化為默認狀態;但每個控件的視圖狀態尚未填充。在 Page_Init 階段中,頁中的控件不能訪問該頁的其他服務器控件,無論其他控件是子控件還是父控件。不一定會創建其他服務器控件,也不一定能夠訪問它們 |
Page | Load | ASP.NET控件完成加載,你寫的UI操作邏輯或任何其他邏輯在這里。 |
Page | Validate | 如果你有你的頁面上有驗證邏輯,這里檢查是否符合驗證。 |
Render | 將頁面最終的輸出發送到瀏覽器,如果你想做出一些最終的HTML的變化,這是輸出到瀏覽器,你可以在這里輸入你的HTML的邏輯。 | |
Page | Unload | 頁面對象從內存中卸載。 |
HttpModule | PostRequestHandlerExecute | 在 ASP.NET 事件處理程序(例如,某頁或某個 XML Web service)執行完畢時發生。 |
HttpModule | ReleaserequestState | 在 ASP.NET 執行完所有請求事件處理程序后發生。該事件將使狀態模塊保存當前狀態數據。引發 ReleaseRequestState 事件以后,應用程序以該請求結束,并發出 ASP.NET 信號以存儲該請求狀態。 |
HttpModule | UpdateRequestCache | Before you end, if you want to update your cache.結束之前,如果您想更新您的高速緩存。 |
HttpModule | EndRequest | 當 ASP.NET 執行完事件處理程序以使緩存模塊存儲將用于從緩存為后續請求提供服務的響應時發生。 |
演示代碼:
在這段代碼中,我們創建HttpModule 和Httphandler 添加所有請求響應的事件, 下面用 HttpModule Httphandler 跟蹤所有活動,并把它添加到一個全局性的集合變量中。
public class clsHttpModule : IHttpModule { private HttpApplication httpApp; public static ArrayList objArrayList = new ArrayList(); public clsHttpModule() { } public void Dispose() { } public void Init(HttpApplication context) { this.httpApp = context; httpApp.Context.Response.Clear(); objArrayList.Clear(); objArrayList.Add("httpModule:Init"); httpApp.AuthenticateRequest += new EventHandler(OnAuthentication); httpApp.AuthorizeRequest += new EventHandler(OnAuthorization); httpApp.BeginRequest += new EventHandler(OnBeginrequest); httpApp.EndRequest += new EventHandler(OnEndRequest); httpApp.ResolveRequestCache += new EventHandler(OnResolveRequestCache); httpApp.AcquireRequestState += new EventHandler(OnAcquireRequestState); httpApp.PreRequestHandlerExecute += new EventHandler(OnPreRequestHandlerExecute); httpApp.PostRequestHandlerExecute += new EventHandler(OnPostRequestHandlerExecute); httpApp.ReleaseRequestState += new EventHandler(OnReleaseRequestState); httpApp.UpdateRequestCache += new EventHandler(OnUpdateRequestCache); } 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>"); } } }
以下代碼片段是跟蹤 HttpHandler 的ProcessRequest '事件' :
public class clsHttpHandler : IHttpHandler { public bool IsReusable { get { return true; } } public void ProcessRequest(HttpContext context) { clsHttpModule.objArrayList.Add("HttpHandler:ProcessRequest"); context.Response.Redirect("~/Default.aspx"); } }
頁面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"); } }
webconfig中配置:
<httpModules> <add name="clsHttpModule" type="WebDemo1.Common.clsHttpModule"/> </httpModules>
頁面***次加載效果:
點擊button按鈕后:
HttpModule
HttpModule通過在某些事件中注冊,把自己插入ASP.NET請求處理管道。當這些事件發生的時候,ASP.NET調用對相應的HTTP模塊,這樣該模塊就能處理請求了。
常用操作:
1、向每個頁面動態添加一些備注或說明性的文字:
2、判斷用戶登錄
如果定義了多個HttpModule,在web.config文件中引入自定義HttpModule的順序就決定了多個自定義HttpModule在處理一個HTTP請求的接管順序。
HttpHandler
HttpHandler是HTTP請求的處理中心,真正地對客戶端請求的服務器頁面做出編譯和執行,并將處理過后的信息附加在HTTP請求信息流中再次返回到HttpModule中。
HttpHandler與HttpModule不同,一旦定義了自己的HttpHandler類,那么它對系統的HttpHandler的關系將是“覆蓋”關系。
為了驗證請求是否進入HttpHandler ,我們可以在WebConfig中 加入:
<add verb="*" path="*.aspx" type="WebDemo1.Common.clsHttpHandler,WebDemo1"/>
調試程序看看。
綜上我們可以總計出一張圖:
ASP.NET頁面事件
在上面的部分,我們已經看到了一個ASP.NET頁面完整的請求事件。 最重要的部分之一,是ASP.NET頁面,我們沒有詳細討論相同。我們詳細討論下ASP.NET的頁面事件。任何ASP.NET頁面中有2個部分 如圖:
注意 :大部分的開發者直接使用page_load方法的一切,這不是一個好的做法。例如 填充控件,設置視圖狀態,應用主題等,這些都是發生在頁面上的負荷。因此,我們可以在適當的事件,添加適當的邏輯,這將真正使你的代碼整潔 符合邏輯。
序號 | 事件 | 控件初始化 | 狀態 是否 可用 | 表單數據是否 可用 | 什么邏輯可以寫在這里? |
1 | Init | No | No | No | OnInit 方法執行創建 Page 實例所需的初始化和設置步驟。在頁生命周期的此階段中,頁中聲明的服務器控件都已初始化為默認狀態;但每個控件的視圖狀態尚未填充。在 Page_Init 階段中,頁中的控件不能訪問該頁的其他服務器控件,無論其他控件是子控件還是父控件。不一定會創建其他服務器控件,也不一定能夠訪問它們。 |
2 | Load view state | Not guaranteed | Yes | Not guaranteed | 您可以訪問視圖狀態和任何同步邏輯 |
3 | PostBackdata | Not guaranteed | Yes | Yes | 你可以訪問表單數據。 |
4 | Load | Yes | Yes | Yes | 綁定控件 等等。。。 |
5 | Validate | Yes | Yes | Yes | 如果你的頁面有驗證,或者你想為您的網頁執行驗證。 |
6 | Event | Yes | Yes | Yes | 如果這是通過點擊一個按鈕或下拉的變化,那么相對應的事件將被執行。 |
7 | Pre-render | Yes | Yes | Yes | 如果你想在這些控件視圖狀態***保存之前修改UI對象的結構或屬性值。 |
8 | Save view state | Yes | Yes | Yes | 一旦所有服務器控件的變化完成,這一事件控制數據保存在視圖狀態。 |
9 | Render | Yes | Yes | Yes | 如果你想添加一些自定義的HTML輸出。 |
10 | Unload | Yes | Yes | Yes | 你可以在這里做任何清理。 |
看完上述內容,你們掌握怎樣看待ASP.NET應用程序與頁面生命周期的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。