在 ASP.NET 中實作 URL 重寫最核心的方式是實作 IHttpHandlerFactory,攔截特定副檔名請求,透過 `context.RewritePath` 內部轉向真實處理頁面。以下提供最精簡、可直接複製部署的完整範例。
<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>
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 內部會處理)
}
}
}
https://site.com/list.zhtml?id=123/web/index.aspxlist.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 後網址變成真實路徑 | 頁面 ` |
| 驗證/授權/Session 失效 | Factory 類別實作 `IRequiresSessionState` |
| 實體檔案 (.css/.js) 被攔截 | IIS 設定「驗證檔案是否存在」取消,或規則加入排除條件 |
| 相對路徑資源 (圖片/CSS) 失效 | 頁面使用根相對路徑 `/css/site.css` 或 `ResolveUrl("~/css/site.css")` |
無需寫代碼,在 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>
理解 `IHttpHandlerFactory` 機制有助於深入掌握 ASP.NET 管線,但生產環境優先選擇成熟基建元件。