ASP.NET 3.5 SP1 引入路由機制,但 Web Forms 整合極其繁瑣:需自訂 IRouteHandler、解析參數存入 HttpContext.Items、手動回傳頁面實例。ASP.NET 4.0 透過 MapPageRoute 等助手方法,實現零自訂 Handler、宣告式配置、參數自動繫結,大幅降低門檻。本文詳細對比新舊做法並示範最佳實踐。
RouteTable.Routes.Add(new Route("Categories/{categoryName}", new CustomRouteHandler("~/ShowProducts.aspx")));GetHttpHandler 中解析 RequestContext.RouteData.Values,存入 HttpContext.Items,回傳 BuildManager.CreateInstanceFromVirtualPath 建立的頁面實例。string cat = Context.Items["categoryName"] as string;void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapPageRoute("CategoryRoute", "Categories/{categoryName}", "~/ShowProducts.aspx");
}
自動獲得:
Page.RouteData.Values["categoryName"]。RouteValueDictionary 預設值、約束條件 (Regex)、實體路由類別。Page.GetRouteUrl("CategoryRoute", new { categoryName = "Beverages" }) 產生 /Categories/Beverages。// 帶約束:categoryName 僅限字母
RouteTable.Routes.MapPageRoute("CategoryRoute",
"Categories/{categoryName}", "~/ShowProducts.aspx",
false,
new RouteValueDictionary { { "categoryName", "All" } }, // 預設值
new RouteValueDictionary { { "categoryName", "[a-zA-Z]+" } } // 約束
);
// 多參數巢狀路由
RouteTable.Routes.MapPageRoute("ProductDetail",
"Categories/{categoryName}/Products/{productId}", "~/ProductDetail.aspx",
constraints: new RouteValueDictionary { { "productId", @"\d+" } });
protected void Page_Load(object sender, EventArgs e)
{
string category = RouteData.Values["categoryName"] as string ?? "All";
int productId = Convert.ToInt32(RouteData.Values["productId"] ?? "0");
// 繫結資料...
}
| 舊做法 (3.5 SP1) | 新做法 (4.0+) | 注意 |
|---|---|---|
| 自訂 IRouteHandler | MapPageRoute / MapRoute | 無需手動建立頁面實例 |
| HttpContext.Items 傳參 | Page.RouteData.Values | 型別安全、IntelliSense 支援 |
| 手動產生 URL | Page.GetRouteUrl / Url.RouteUrl | 自動套用路由規則,避免硬編碼 |
| 僅支援 Web Forms | 統一 RouteTable 共用 MVC/Web Forms | 同一應用程式可混合兩種框架 |
ASP.NET 4.0 將路由從「專家級黑魔法」降維為「宣告式基礎設施」。新專務必採用 MapPageRoute;舊專案升級 4.0 時,建議漸進式替換自訂 Handler,獲得更清晰、可維護、SEO 友善的 URL 架構。