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

ASP.NET 管線事件與 HttpHandler/HttpModule 深度解析:從請求處理到模組化架構

     編輯:ASP.NET 基礎

前言:揭開 ASP.NET 處理請求的神秘面紗

許多 ASP.NET 開發者習慣在頁面層級撰寫程式碼,卻對請求在伺服器端的完整生命週期知之甚少。理解 ASP.NET 管線事件、HttpHandler 與 HttpModule,能讓我們從「頁面級開發」進階為「請求級架構」,實現跨頁面的共用邏輯、URL 重寫、防盜鏈、認證授權等進階功能。

ASP.NET 請求處理管線 24 個關鍵事件

從瀏覽器發出請求到回應完成,ASP.NET 會依序觸發以下事件(IIS 7+ 整合模式下):

  1. BeginRequest:請求開始
  2. AuthenticateRequest:身分驗證
  3. PostAuthenticateRequest
  4. AuthorizeRequest:授權檢查
  5. PostAuthorizeRequest
  6. ResolveRequestCache:輸出快取解析
  7. PostResolveRequestCache
  8. MapRequestHandler:依副檔名對應 HttpHandler(第 10 步)
  9. PostMapRequestHandler
  10. AcquireRequestState:取得 Session 等狀態
  11. PostAcquireRequestState
  12. PreRequestHandlerExecute
  13. 執行 Handler 的 ProcessRequest 方法(第 15 步)
  14. PostRequestHandlerExecute
  15. ReleaseRequestState:釋放狀態
  16. PostReleaseRequestState
  17. UpdateRequestCache:更新輸出快取
  18. PostUpdateRequestCache
  19. EndRequest:請求結束(唯一保證觸發的事件)
  20. PreSendRequestHeaders、PreSendRequestContent:發送回應前

關鍵提醒:事件順序固定,但中途若呼叫 Response.End() 或發生未處理例外,後續事件將不再觸發。

HttpHandler:針對特定副檔名的請求處理器

核心概念

HttpHandler 實作 IHttpHandler 介面,負責處理特定副檔名(如 .aspx、.ashx、.jpg)的請求。在 web.config 的 <httpHandlers> 區段定義對應關係:

<httpHandlers>
  <add verb="*" path="*.aspx" type="System.Web.UI.PageHandlerFactory" />
  <add verb="*" path="*.ashx" type="System.Web.UI.SimpleHandlerFactory" />
  <add verb="*" path="*.jpg" type="MyNamespace.ImageHandler, MyAssembly" />
</httpHandlers>

觸發時機:管線第 10 步 (MapRequestHandler) 選擇 Handler,第 15 步執行 ProcessRequest。

實戰範例:圖片防盜鏈 HttpHandler

攔截所有 .jpg 請求,檢查 Referer 標頭,非本站來源則回傳預設圖片:

public class AntiHotlinkHandler : IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        string filePath = context.Server.MapPath(context.Request.FilePath);
        var referer = context.Request.UrlReferrer;

        if (referer == null || !referer.Host.Contains("yourdomain.com"))
        {
            context.Response.ContentType = "image/gif";
            context.Response.WriteFile("/images/hotlink-denied.gif");
            return;
        }

        context.Response.ContentType = "image/jpeg";
        context.Response.WriteFile(filePath);
    }

    public bool IsReusable => true; // 可重用,減少物件建立開銷
}

註冊於 web.config:

<add verb="*" path="*.jpg" type="MyProject.AntiHotlinkHandler, MyProject" />

HttpModule:全域請求攔截與管線事件訂閱

核心差異

特性HttpHandlerHttpModule
作用範圍特定副檔名/路徑所有請求
介面IHttpHandlerIHttpModule
觸發點管線固定步驟 (10/15)可訂閱任一管線事件
典型用途輸出圖片、RSS、自訂副檔名認證、日誌、URL 重寫、壓縮、Session 管理

實作 IHttpModule


public class CustomAuthModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        // 訂閱管線事件
        context.AuthenticateRequest += OnAuthenticateRequest;
        context.BeginRequest += OnBeginRequest;
        context.EndRequest += OnEndRequest;
    }

    private void OnAuthenticateRequest(object sender, EventArgs e)
    {
        var app = (HttpApplication)sender;
        // 自訂驗證邏輯:檢查 Token、Cookie、Header 等
        if (!IsValidRequest(app.Request))
        {
            app.Response.StatusCode = 401;
            app.CompleteRequest(); // 短路管線,直接結束請求
        }
    }

    private void OnBeginRequest(object sender, EventArgs e)
    {
        // 記錄請求資訊、URL 重寫、IP 封鎖等
    }

    public void Dispose() { /* 清理資源 */ }
}

註冊於 web.config(IIS 7+ 整合模式請用 <system.webServer>):

<system.webServer>
  <modules>
    <add name="CustomAuthModule" type="MyProject.CustomAuthModule, MyProject" />
  </modules>
</system.webServer>

進階應用場景

  • URL 重寫/路由:在 BeginRequest 或 PostMapRequestHandler 修改 Context.RewritePath()。
  • GZIP 壓縮回應:在 PostRequestHandlerExecute 檢查 Accept-Encoding 標頭,包裝 Response.Filter。
  • 統一異常處理:在 Error 事件記錄日誌、導向友善錯誤頁。
  • 效能監控:在 BeginRequest/EndRequest 計算耗時、記錄慢查詢。

總結

掌握 ASP.NET 管線事件順序,善用 HttpHandler 處理特定資源型別、HttpModule 實作橫切關注點,是打造可維護、高擴充性 Web 應用的關鍵。下次面對跨頁面共用邏輯時,請優先考慮模組化方案,而非在每個頁面重複撰寫程式碼。

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