首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET Global.asax 全域應用程式類別完整事件生命週期解析

     編輯:ASP.NET 基礎

前言

Global.asax(全域應用程式類別)是 ASP.NET 應用程式的進入點,包含應用程式層級與工作階段層級的事件處理程式。每個應用程式僅能有一個 Global.asax,置於專案根目錄。本文詳細解析各事件觸發時機、適用場景與實務注意事項。

核心事件完整列表與說明

事件名稱觸發時機典型用途注意事項
Application_Start 應用程式接收第一個請求時,僅觸發一次 初始化靜態資料、註冊路由、設定 DI 容器、啟動背景工作、載入快取 此時 Session 尚不可用;若初始化失敗,應用程式無法啟動
Session_Start 每位使用者首次造訪(建立新 Session)時 初始化使用者專屬 Session 變數、線上人數計數、購物車初始化 僅在 mode="InProc" 或 StateServer/SQLServer 時觸發;cookieless="true" 時依 URL 識別
Application_BeginRequest 每個 HTTP 請求進入管線最前端 URL 重寫、多語系文化切換、記錄請求日誌、IP 封鎖、SSL 強制導向 執行最早,影響所有後續處理;避免耗時操作
Application_AuthenticateRequest 驗證階段,確認使用者身分 自訂驗證邏輯(如從 Token 解析 Principal、設定 HttpContext.User) 在 Forms 驗證票解密後觸發,可覆寫 Principal
Application_Error 未處理的例外拋出時 統一錯誤記錄(寫入資料庫/檔案/ELMAH)、友善錯誤頁面導向、發送警報通知 務必呼叫 Server.ClearError() 避免預設黃色錯誤頁;記錄完整堆疊
Session_End Session 逾時或主動 Abandon() 時(僅 InProc 模式) 清理使用者資源、釋放鎖定、記錄離線時間、更新線上人數 StateServer/SQLServer 模式不觸發;執行緒非請求執行緒,無 HttpContext
Application_End 應用程式關閉(IIS 回收、web.config 變更、手動停止) 釋放非受控資源、關閉資料庫連線池、停止背景工作、持久化快取 ASP.NET 會自動清理大部分資源,通常無需大量程式碼

實務最佳實踐範例

1. Application_Start:路由、DI、快取初始化

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    
    // 自訂初始化
    DependencyConfig.Register();      // Autofac/Unity 等 DI 容器
    CacheManager.WarmUp();            // 預熱熱門資料
    TaskScheduler.StartBackgroundJobs(); // 排程任務
}

2. Application_Error:統一異常處理與記錄

protected void Application_Error(object sender, EventArgs e)
{
    var ex = Server.GetLastError();
    var httpEx = ex as HttpException;
    
    // 記錄完整資訊
    Logger.Fatal("Unhandled Exception", ex);
    
    // 404 導向自訂頁面
    if (httpEx != null && httpEx.GetHttpCode() == 404)
    {
        Server.ClearError();
        Response.Redirect("/Error/NotFound");
        return;
    }
    
    // 其他錯誤導向通用錯誤頁
    Server.ClearError();
    Response.Redirect("/Error/Index");
}

3. Application_BeginRequest:強制 HTTPS 與多語系

protected void Application_BeginRequest()
{
    // 強制 HTTPS
    if (!Context.Request.IsSecureConnection && !Context.Request.IsLocal)
    {
        var builder = new UriBuilder(Context.Request.Url) { Scheme = "https", Port = 443 };
        Response.Redirect(builder.Uri.ToString());
    }
    
    // 從 Cookie/Header 判斷語系
    var culture = Context.Request.Cookies["lang"]?.Value ?? "zh-TW";
    Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
}

常見誤區與提醒

  1. 不要在 Application_Start 存取 Session/Request/Response:此時 HttpContext 尚未建立。
  2. Session_End 僅在 InProc 生效:Web Farm 必須改用 StateServer/SQLServer,並改用資料庫排程清理過期資料。
  3. Application_Error 不會捕獲 Web API / MVC 全域過濾器已處理的異常:需配合 HandleErrorAttribute 或 ExceptionFilterAttribute。
  4. 避免在 BeginRequest 做重 I/O:會嚴重拖慢所有請求回應速度。

總結

熟悉 Global.asax 事件生命週期,能讓你在正確的時間點執行正確的邏輯:啟動初始化、請求管線攔截、異常統一處理、資源優雅釋放。建議團隊建立標準模板,統一錯誤處理與啟動流程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved