URL Rewriting(網址重寫) 是在伺服器端攔截傳入請求的 URL,依規則轉換為內部實際處理的 URL,過程對瀏覽器完全透明。使用者看到的是乾淨、有語意的網址,伺服器實際執行的是帶參數的動態頁面。
/products/widgets 比 /displayCategory.aspx?CategoryID=5 易記、易傳播、易猜測。public class UrlRewriteModule : IHttpModule
{
private static readonly List _rules = new List
{
new RewriteRule(@"^/products/([^/]+)/?$", "/displayCategory.aspx?category=$1"),
new RewriteRule(@"^/product/(\d+)/?$", "/productDetail.aspx?id=$1"),
new RewriteRule(@"^/blog/(\d{4})/(\d{2})/(\d{2})/([^/]+)/?$", "/blogPost.aspx?y=$1&m=$2&d=$3&slug=$4")
};
public void Init(HttpApplication context)
{
context.BeginRequest += (s, e) => {
HttpApplication app = (HttpApplication)s;
string path = app.Request.Path;
foreach (var rule in _rules)
{
Match m = rule.Pattern.Match(path);
if (m.Success)
{
string newUrl = rule.Replacement;
for (int i = 1; i < m.Groups.Count; i++)
newUrl = newUrl.Replace("$" + i, m.Groups[i].Value);
app.Context.RewritePath(newUrl);
break;
}
}
};
}
public void Dispose() { }
class RewriteRule { public Regex Pattern; public string Replacement; public RewriteRule(string pattern, string repl) { Pattern = new Regex(pattern, RegexOptions.IgnoreCase); Replacement = repl; } }
}
web.config 註冊(IIS 7+ 整合管線):
<system.webServer>
<modules>
<add name="UrlRewriteModule" type="MyApp.UrlRewriteModule, MyApp" />
</modules>
</system.webServer>
void Application_Start()
{
RouteTable.Routes.MapPageRoute("ProductsByCategory", "products/{categoryName}", "~/displayCategory.aspx");
RouteTable.Routes.MapPageRoute("ProductDetail", "product/{id:int}", "~/productDetail.aspx");
RouteTable.Routes.MapPageRoute("BlogPost", "blog/{year:int}/{month:int}/{day:int}/{slug}", "~/blogPost.aspx");
}
RouteData.Values["categoryName"] 或 Page.RouteData.Values["id"]。Page.GetRouteUrl("ProductsByCategory", new { categoryName = "widgets" }) 產生美化 URL。<system.webServer>
<rewrite>
<rules>
<rule name="ProductsCategory" stopProcessing="true">
<match url="^products/([^/]+)/?$" />
<action type="Rewrite" url="displayCategory.aspx?category={R:1}" />
</rule>
<rule name="ProductDetail" stopProcessing="true">
<match url="^product/(\d+)/?$" />
<action type="Rewrite" url="productDetail.aspx?id={R:1}" />
</rule>
<rule name="LegacyAspxRedirect" stopProcessing="true">
<match url="^displayCategory\.aspx$" />
<conditions>
<add input="{QUERY_STRING}" pattern="CategoryID=(\d+)" />
</conditions>
<action type="Redirect" url="products/{C:1}/" redirectType="Permanent" />
</rule>
</rules>
</rewrite>
</system.webServer>
重寫後頁面回傳會導向重寫前的 URL,造成網址變醜。解決:
form.Action = Request.RawUrl; 在 Page_Load 設定。ControlAdapter 覆寫 RenderBeginTag 自動修正。/en/products/widgets
/zh-tw/products/widgets
/ja/products/widgets
Routing 方案:RouteTable.Routes.MapPageRoute("LocalProducts", "{lang}/products/{category}", "~/displayCategory.aspx");
IRouteConstraint 或 Rewrite Map。301 Moved Permanently。| 需求 | 推薦方案 | 理由 |
|---|---|---|
| ASP.NET 2.0 / IIS 6 相容、需程式碼控制邏輯 | HttpModule | 純 managed code、部署簡單、可單元測試 |
| ASP.NET 4.0+、Web Forms、想要雙向產生 URL | ASP.NET Routing | 內建、型別安全、支援 GetRouteUrl |
| IIS 7+、追求最高效能、零程式碼、SEO 301、Rewrite Map | URL Rewrite Module 2.0 | 原生模組、效能最佳、支援對應表、條件、記錄 |
URL Rewriting 是現代 Web 應用的標準配備。無論選擇 HttpModule、Routing 或 IIS Rewrite Module,核心原則相同:對外呈現乾淨語意網址,內部解耦實體結構。善用重寫技術不僅能美化網址、提升 SEO,更能優雅地處理網站重構、多語系、舊連結遷移與智慧 404,是提升專案專業度的關鍵技術之一。