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

ASP.NET URL 重寫簡易實作:IHttpHandlerFactory 最小範例

     編輯:關於ASP.NET

在 ASP.NET 中實作 URL 重寫最核心的方式是實作 IHttpHandlerFactory,攔截特定副檔名請求,透過 `context.RewritePath` 內部轉向真實處理頁面。以下提供最精簡、可直接複製部署的完整範例。

三步驟完成部署

1. IIS 設定副檔名對應 (關鍵:讓 ASP.NET 處理自訂副檔名)

  • IIS 6 / 經典模式:網站內容 → 應用程式設定 → 對應 → 加入 `.zhtml` → 可執行檔指向 `aspnet_isapi.dll`、勾選「驗證檔案是否存在」取消
  • IIS 7+ 整合模式:處理常式對應 → 加入受管理處理常式 → 請求路徑 `*.zhtml`、類型選擇自訂 Factory、取消「要求存取」核取方塊

2. Web.config 註冊 HttpHandler Factory


<system.web> <!-- IIS 6 / 經典模式 -->
    <httpHandlers>
        <add verb="*" path="*.zhtml" type="MyApp.UrlRewriter.RewriterFactoryHandler, MyApp" />
    </httpHandlers>
</system.web>

<system.webServer> <!-- IIS 7+ 整合模式 -->
    <handlers>
        <add name="UrlRewriter" verb="*" path="*.zhtml" 
             type="MyApp.UrlRewriter.RewriterFactoryHandler, MyApp" 
             preCondition="integratedMode" />
    </handlers>
</system.webServer>

3. 實作 RewriterFactoryHandler


using System;
using System.Web;
using System.Web.UI;

namespace MyApp.UrlRewriter
{
    public class RewriterFactoryHandler : IHttpHandlerFactory
    {
        public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
        {
            // 1. 目標真實頁面 (可從 url 解析參數決定)
            string targetPage = "/web/index.aspx"; 
            string queryString = context.Request.QueryString.ToString(); // 保留原查詢字串

            // 2. 取得真實頁面實體路徑
            string physicalPath = context.Server.MapPath(targetPage);

            // 3. 核心:內部重寫路徑 (瀏覽器網址列不變)
            context.RewritePath(targetPage, string.Empty, queryString);

            // 4. 回傳編譯後的頁面處理常式
            return PageParser.GetCompiledPageInstance(url, physicalPath, context);
        }

        public void ReleaseHandler(IHttpHandler handler)
        {
            // 釋放資源 (PageHandlerFactory 內部會處理)
        }
    }
}

運作流程圖解

  1. 瀏覽器請求 https://site.com/list.zhtml?id=123
  2. IIS 依副檔名 `.zhtml` 導向 ASP.NET 管線
  3. `RewriterFactoryHandler.GetHandler` 被呼叫
  4. `context.RewritePath("/web/index.aspx", "", "id=123")` 內部轉向
  5. `PageParser.GetCompiledPageInstance` 載入/編譯 /web/index.aspx
  6. 頁面正常執行生命週期,`Request.QueryString["id"]` 可取得 "123"
  7. 回應輸出給瀏覽器,網址列仍顯示 list.zhtml?id=123

進階:動態解析重寫規則


public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)
{
    // 從設定檔/資料庫讀取規則字典
    var rules = UrlRewriteConfig.GetRules(); // Dictionary 虛擬路徑 -> 真實路徑
    
    string virtualPath = context.Request.Path; // /list.zhtml
    if (rules.TryGetValue(virtualPath, out string realPath))
    {
        context.RewritePath(realPath, string.Empty, context.Request.QueryString.ToString());
        return PageParser.GetCompiledPageInstance(url, context.Server.MapPath(realPath), context);
    }
    
    // 無對應規則:回傳 404 或預設處理
    context.Response.StatusCode = 404;
    return new HttpNotFoundHandler(); // 需自訂實作 IHttpHandler
}

注意事項與坑點

問題解決
瀏覽器網址列跳轉 (302)使用 `context.RewritePath` (內部轉向),而非 `Response.Redirect`
Postback 後網址變成真實路徑頁面 `
` 留空,或 `Page.Form.Action = Request.RawUrl`
驗證/授權/Session 失效Factory 類別實作 `IRequiresSessionState`
實體檔案 (.css/.js) 被攔截IIS 設定「驗證檔案是否存在」取消,或規則加入排除條件
相對路徑資源 (圖片/CSS) 失效頁面使用根相對路徑 `/css/site.css` 或 `ResolveUrl("~/css/site.css")`

現代替代:IIS URL Rewrite Module (強烈建議)

無需寫代碼,在 Web.config 宣告式設定:


<system.webServer>
    <rewrite>
        <rules>
            <rule name="RewriteZhtml" stopProcessing="true">
                <match url="^(.*)\.zhtml$" />
                <action type="Rewrite" url="/web/index.aspx" appendQueryString="true" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>
  • 效能更好 (原生模組)、支援輸出快取、完美相容所有 ASP.NET 功能、可視化管理、正規表達式功能強大。
  • **新專案請直接使用此方案**,僅在極舊環境 (IIS 6 無法安裝模組) 才需自訂 Factory。

理解 `IHttpHandlerFactory` 機制有助於深入掌握 ASP.NET 管線,但生產環境優先選擇成熟基建元件。

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