IIS 5.0 和 6.0 的 ASP.NET 應用程式生命週期概觀

更新:2007 年 11 月

本主題概述 ASP.NET 應用程式的生命週期、列出重要的生命週期事件,以及說明您所撰寫的程式碼如何配合應用程式生命週期。本主題中的資訊適用於 IIS 5.0 和 IIS 6.0。如需 IIS 7.0 中 ASP.NET 應用程式生命週期的詳細資訊,請參閱 IIS 7.0 的 ASP.NET 應用程式生命週期概觀

在 ASP.NET 中,初始化 ASP.NET 應用程式和處理要求時必須執行幾個處理步驟。此外,ASP.NET 只是 Web 伺服器架構的一部分,以服務瀏覽器提出的要求。了解應用程式生命週期是很重要的,讓您能夠在適當的生命週期階段,撰寫達到所需效果的程式碼。

一般應用程式生命週期

下列表格描述 ASP.NET 應用程式生命週期的階段。

階段

描述

使用者要求 Web 伺服器上的應用程式資源。

ASP.NET 應用程式的生命週期開始於瀏覽器傳送要求至 Web 伺服器 (對 ASP.NET 應用程式而言通常是 IIS)。ASP.NET 是 Web 伺服器下的 ISAPI 擴充程式。當 Web 伺服器收到要求時,會檢查要求檔案的副檔名、判斷應該處理要求的 ISAPI 擴充程式,然後將要求傳遞至適當的 ISAPI 擴充程式。ASP.NET 會處理已對應的副檔名,例如 .aspx、.ascx、.ashx 和 .asmx。

注意事項:
如果副檔名尚未對應至 ASP.NET,則 ASP.NET 就不會收到要求。了解這項特性對使用 ASP.NET 驗證的應用程式而言是很重要的。例如,因為 .htm 檔通常不會對應至 ASP.NET,所以 ASP.NET 不會對 .htm 檔執行驗證或授權檢查。因此,即使檔案只包含靜態內容,如果您想要 ASP.NET 檢查驗證,請使用對應至 ASP.NET 的副檔名 (像是 .aspx) 建立檔案。
注意事項:
如果您建立服務特定副檔名的自訂處理常式,就必須將副檔名對應至 IIS 中的 ASP.NET,並且也要在應用程式的 Web.config 檔中註冊處理常式。如需詳細資訊,請參閱 HTTP 處理常式和 HTTP 模組概觀

ASP.NET 會接收應用程式的第一個要求。

當 ASP.NET 接收應用程式中任何資源的第一個要求時,名為 ApplicationManager 的類別會建立應用程式定義域。應用程式定義域可以隔離應用程式間的全域變數,而且能夠允許每個應用程式個別進行卸載。在應用程式定義域中,會建立名為 HostingEnvironment 類別的執行個體,以提供應用程式資訊的存取,例如儲存應用程式的資料夾名稱。

下列圖表說明這項關係:

ASP.NET 也會視需要編譯應用程式中最上層的項目,包括 App_Code 資料夾中的應用程式碼。如需詳細資訊,請參閱稍後這個主題中的「編譯生命週期」。

每個要求都會建立 ASP.NET 核心物件。

在建立應用程式定義域和產生 HostingEnvironment 物件後,ASP.NET 會建立和初始化核心物件,例如 HttpContextHttpRequestHttpResponseHttpContext 類別包含目前應用程式要求的特定物件,例如 HttpRequestHttpResponse 物件。HttpRequest 物件包含目前要求的資訊,包括 Cookie 和瀏覽器資訊。HttpResponse 物件包含傳送至用戶端的回應,包括所有呈現的輸出和 Cookie。

HttpApplication 物件會指派給要求。

在初始化所有核心應用程式物件後,會藉由建立 HttpApplication 類別的執行個體來啟動應用程式。如果應用程式有 Global.asax 檔,ASP.NET 會改為建立衍生自 HttpApplication 類別的 Global.asax 類別執行個體,然後使用衍生的類別代表應用程式。

注意事項:
當第一次在應用程式中要求 ASP.NET Web 網頁或處理序時,就會建立新的 HttpApplication 執行個體。然而,若要讓效能最佳化,多重處理序可能會重複使用 HttpApplication 執行個體。

當建立 HttpApplication 的執行個體時,也會建立任何設定的模組。例如,如果應用程式設定為執行這項動作,ASP.NET 就會建立 SessionStateModule 模組。在建立所有設定的模組後,就會呼叫 HttpApplication 類別的 Init 方法。

下列圖表說明這項關係:

HttpApplication 管線會處理這項要求。

當處理要求時,HttpApplication 類別會執行下列事件。這些事件對擴充 HttpApplication 類別的開發人員特別有用。

  1. 驗證要求會檢查瀏覽器傳送的資訊,然後判斷是否包含潛在惡意標記。如需詳細資訊,請參閱 ValidateRequest指令碼攻擊概觀

  2. 如果在 Web.config 檔的 UrlMappingsSection 區段中設定任何 URL,就執行 URL 對應。

  3. 引發 BeginRequest 事件。

  4. 引發 AuthenticateRequest 事件。

  5. 引發 PostAuthenticateRequest 事件。

  6. 引發 AuthorizeRequest 事件。

  7. 引發 PostAuthorizeRequest 事件。

  8. 引發 ResolveRequestCache 事件。

  9. 引發 PostResolveRequestCache 事件。

  10. 根據要求資源的副檔名 (對應在應用程式的組態檔中),選取實作 IHttpHandler 以處理要求的類別。如果要求是針對衍生自 Page 類別的物件 (網頁) 並且需要編譯網頁,ASP.NET 會在建立網頁的執行個體之前進行編譯。

  11. 引發 PostMapRequestHandler 事件。

  12. 引發 AcquireRequestState 事件。

  13. 引發 PostAcquireRequestState 事件。

  14. 引發 PreRequestHandlerExecute 事件。

  15. 呼叫要求之適當 IHttpHandler 類別的 ProcessRequest 方法 (或是非同步版本 IHttpAsyncHandler.BeginProcessRequest)。例如,如果是要求網頁,目前的網頁執行個體就會處理要求。

  16. 引發 PostRequestHandlerExecute 事件。

  17. 引發 ReleaseRequestState 事件。

  18. 引發 PostReleaseRequestState 事件。

  19. 如果有定義 Filter 屬性就執行回應篩選。

  20. 引發 UpdateRequestCache 事件。

  21. 引發 PostUpdateRequestCache 事件。

  22. 引發 EndRequest 事件。

  23. 引發 PreSendRequestHeaders 事件。

  24. 引發 PreSendRequestContent 事件。

生命週期事件和 Global.asax 檔

在應用程式生命週期期間,應用程式會引發能夠處理的事件,並且呼叫能夠覆寫的特定方法。若要處理應用程式事件或方法,您可以在應用程式根目錄中建立名為 Global.asax 的檔案。

如果您建立 Global.asax 檔,ASP.NET 會將其編譯為衍生自 HttpApplication 類別的類別,然後使用衍生的類別代表應用程式。

HttpApplication 執行個體一次只會處理一個要求。因為您不需要在應用程式類別中鎖定要存取的非靜態成員,所以能夠簡化應用程式事件處理。這也可以讓您將要求特定資料儲存在應用程式類別的非靜態成員中。例如,您可以在 Global.asax 檔中定義屬性,然後將要求特定值指派給它。

ASP.NET 會使用命名規範 Application_event (例如,Application_BeginRequest),自動將應用程式事件繫結至 Global.asax 檔案中的處理常式。這類似 ASP.NET Web 網頁方法會自動繫結至事件的方式,例如網頁的 Page_Load 事件。如需詳細資訊,請參閱 ASP.NET 網頁存留週期概觀

Application_Start 和 Application_End 方法是不代表 HttpApplication 事件的特殊方法。ASP.NET 會在應用程式定義域的存留期呼叫一次這些方法,而不是為每個 HttpApplication 執行個體呼叫。

下列表格列出在應用程式生命週期會使用的某些事件和方法。除了這些列出的以外還有許多事件,但是並不常使用到。

事件或方法

描述

Application_Start

當要求 ASP.NET 應用程式中的第一個資源 (例如網頁) 時呼叫。Application_Start 方法只會在應用程式生命週期內呼叫一次。您可以使用這個方法執行啟動工作,例如將資料載入快取和初始化靜態值。

在應用程式啟動期間您應該只設定靜態資料。因為只有所建立 HttpApplication 類別的第一個執行個體才能使用,所以請勿設定任何執行個體資料。

Application_event

在應用程式生命週期的適當時機引發,如同在本主題稍早的應用程式生命週期資料表中所列出的。

Application_Error 可以在應用程式生命週期的任意階段引發。

因為可以繞過要求,所以在每個要求中只有保證會引發 Application_EndRequest 事件。例如,如果有兩個模組處理 Application_BeginRequest 事件然後第一個模組擲回例行狀況,就不會為第二個模組呼叫 Application_BeginRequest 事件。然而,一定會呼叫 Application_EndRequest 方法以便讓應用程式清除資源。

Init

在建立所有模組後,HttpApplication 類別的每個執行個體都會呼叫一次。

Dispose

在終結應用程式執行個體之前呼叫。您可以使用這個方法手動釋放任何 Unmanaged 資源。如需詳細資訊,請參閱清除 Unmanaged 資源

Application_End

在卸載應用程式之前,應用程式的每個存留期都呼叫一次。

編譯生命週期

第一次要求應用程式時,ASP.NET 就會按特定的順序編譯應用程式項目。第一批要編譯的項目稱為最上層項目。在第一次要求後,只有相依性變更時,才會重新編譯最上層項目。下表將說明 ASP.NET 最上層項目的編譯順序。

項目

描述

App_GlobalResources

編譯應用程式的全域資源,而且會建置資源組件。應用程式 Bin 資料夾中的任何組件都會連結至此資源組件。

App_WebResources

建立並編譯 Web 服務的 Proxy 型別。產生的 Web 參考組件會連結至資源組件 (如果它存在的話)。

Web.config 檔中定義的設定檔屬性

如果設定檔屬性是在應用程式的 Web.config 檔中定義,就會產生含有設定檔物件的組件。

App_Code

建置原始程式碼檔,而且會建立一個或多個組件。所有程式碼組件和設定檔組件都會連結至資源和 Web 參考組件 (如果有的話)。

Global.asax

編譯應用程式物件並連結至所有之前產生的組件。

當應用程式的最上層項目都編譯完成後,ASP.NET 就會視需要編譯資料夾、頁面和其他項目。下表將說明 ASP.NET 資料夾和項目的編譯順序。

項目

描述

App_LocalResources

如果內含所要求項目的資料夾含有 App_LocalResources 資料夾,就會編譯本機資源資料夾的內容並連結至全域資源組件。

個別的 Web 網頁 (.aspx 檔)、使用者控制項 (.ascx 檔)、HTTP 處理常式 (.ashx 檔) 和 HTTP 模組 (.asmx 檔)

視需要編譯並連結至本機資源組件和最上層組件。

佈景主題、主版頁面和其他原始程式檔

當參考的頁面編譯後,就會編譯頁面所參考之個別佈景主題、主版頁面和其他原始程式檔的面板檔案。

在伺服器上會快取已編譯的組件以及在後續要求時重複使用,而且只要原始程式碼未變更就會保留至應用程式重新啟動。

由於應用程式是在第一次要求時編譯,所以應用程式的初始要求明顯會比後續要求花費較長的時間。您可以先行編譯應用程式,以減少第一次要求所需的時間。如需詳細資訊,請參閱HOW TO:先行編譯 ASP.NET 網站

應用程式重新啟動

修改 Web 應用程式的原始程式碼會讓 ASP.NET 將原始程式檔重新編譯成組件。當您修改應用程式中的最上層項目時,應用程式中所有其他參考最上層組件的組件也會一併重新編譯。

此外,在應用程式的已知資料夾內修改、加入或刪除某些檔案類型將會導致應用程式重新啟動。下列動作將會導致應用程式重新啟動:

  • 從應用程式的 Bin 資料夾中加入、修改或刪除組件。

  • 從 App_GlobalResources 或 App_LocalResources 資料夾中加入、修改或刪除當地語系化資源。

  • 加入、修改或刪除應用程式的 Global.asax 檔。

  • 在 App_Code 目錄中加入、修改或刪除原始程式碼檔。

  • 加入、修改或刪除設定檔組態。

  • 在 App_WebReferences 目錄中加入、修改或刪除 Web 服務參考。

  • 加入、修改或刪除應用程式的 Web.config 檔。

當要求應用程式重新啟動時,ASP.NET 會先服務現有應用程式定義域和舊組件中的所有暫止要求,然後再重新啟動應用程式定義域並載入新的組件。

HTTP 模組

您可以經由 IHttpModule 類別擴充 ASP.NET 應用程式生命週期。ASP.NET 會包含實作 IHttpModule 的幾個類別,例如 SessionStateModule 類別。您也可以建立實作 IHttpModule 類別。

如果您將模組加入應用程式,模組本身就能夠引發事件。應用程式可以使用慣例 modulename_eventname,在 Global.asax 檔案中訂閱這些事件。例如,若要處理 FormsAuthenticationModule 物件引發的 Authenticate 事件,您可以建立名為 FormsAuthentication_Authenticate 的處理常式。

在 ASP.NET 中,預設為啟用 SessionStateModule 類別。所有工作階段事件都會自動連線為 Session_event,例如 Session_Start。每次建立新的工作階段時都會引發 Start 事件。如需詳細資訊,請參閱ASP.NET 工作階段狀態概觀

請參閱

概念

ASP.NET 網頁存留週期概觀

ASP.NET 概觀

ASP.NET 編譯概觀

其他資源

ASP.NET 和 IIS 組態