ASP.NET 頁面請求經過一系列受管物件管線,從 URL 解析到 HTML 輸出。理解 `HttpRuntime`、`HttpApplication`、`PageHandlerFactory`、`Page` 類別的協作關係,以及頁面生命週期各階段事件,是掌握 WebForms 開發、除錯、效能調優的核心基礎。本文系統梳理完整流程。
用戶請求 (.aspx) → HttpRuntime (每個 AppDomain 單例) → HttpApplication (從池取得) → HttpHandler 對應 (web.config/machine.config) → PageHandlerFactory.GetHandler() → 動態編譯 .aspx → 類別 (命名空間 ASP,類名如 Page_aspx) → 實例化 Page 衍生類別 → Page.ProcessRequest() 啟動生命週期
Object
└─ Control
└─ TemplateControl
└─ Page (實作 IHttpHandler)
└─ 動態生成的頁面類別 (含使用者程式碼)
└─ CodeBehind 基底類別 (若指定)
└─ 自訂基底類別
| 階段 | 核心方法/事件 | 說明 |
|---|---|---|
| 1. 初始化 | `FrameworkInitialize()` `Page_Init` | 建立控制項樹、聲明式控制項實例化、Theme 套用 |
| 2. 載入 ViewState / 回發資料 | `LoadViewState()` `ProcessPostData()` | 還原控制項狀態、處理表單回發值 (IPostBackDataHandler) |
| 3. 載入 | `Page_Load` | 使用者商業邏輯、資料繫結、狀態檢查 |
| 4. 回發事件處理 | `RaisePostBackEvent()` `Button_Click` 等 | 觸發按鈕點擊、下拉選單變更等伺服器端事件 |
| 5. 預渲染 / 渲染 | `Page_PreRender` `SaveViewState()` `Render()` | 最後修改機會、序列化 ViewState、輸出 HTML |
| 6. 卸載 | `Page_Unload` | 釋放資源、關閉連線、清理非受管物件 |
ASP.NET 支援兩種事件訂閱方式:
建議:**關閉 `AutoEventWireup`,改用顯式訂閱**,避免效能損耗與命名衝突。
<%@ Page Language="C#" CodeBehind="Default.aspx.cs"
Inherits="MyApp.Default" %>
// Default.aspx.cs
public partial class Default : System.Web.UI.Page { ... }
| 現象 | 排查方向 |
|---|---|
| 事件不觸發 | 檢查 `AutoEventWireup`、方法簽名、`IsPostBack` 邏輯 |
| ViewState 遺失 | 確認 `EnableViewState`、控制項樹結構一致、無動態新增未重建 |
| 動態控制項事件失效 | 必須在 `Page_Init` 或 `Page_Load` (IsPostBack 前) 重建 |
| 效能差 | 分析 `Page_Load` 資料庫呼叫、ViewState 大小、渲染輸出 |
掌握頁面物件模型與生命週期,不只是為了通過面試,更是為了在 Legacy 系統中精準定位問題、安全重構、平滑遷移至現代架構。