Routing 是 ASP.NET MVC **第一個管線環節**:將傳入 URL 解析為 {controller}, {action}, {id} 等路由值,決定請求由哪個 Controller/Action 處理。本文從基礎 MapRoute 到進階 **路由約束、區域、子域名、測試策略**,完整解析 System.Web.Routing 核心機制。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); // 排除 WebResource.axd 等
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { id = @"\d+" } // 可選:id 必須為數字
);
// 更多路由...
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
// 其他初始化...
}
RouteCollection。Route.GetRouteData(HttpContextBase) 嘗試匹配請求 URL。RouteData (含 Values, DataTokens, Route, RouteHandler)。// 內建約束
constraints: new { id = @"\d+", action = "Index|About|Contact" }
// 自訂約束:實作 IRouteConstraint
public class LocalhostConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
return httpContext.Request.IsLocal; // 僅允許本機請求
}
}
// 使用
constraints: new { isLocal = new LocalhostConstraint() }
// AreaRegistration.cs (各區域自行註冊)
public class AdminAreaRegistration : AreaRegistration
{
public override string AreaName => "Admin";
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Admin_default",
"Admin/{controller}/{action}/{id}",
new { controller = "Dashboard", action = "Index", id = UrlParameter.Optional }
);
}
}
// Global.asax 統一掃描
AreaRegistration.RegisterAllAreas();
// 需自訂 RouteBase 或使用第三方庫 (如 AttributeRouting)
public class SubdomainRoute : Route
{
private readonly string _subdomain;
public SubdomainRoute(string subdomain, string url, IRouteHandler handler)
: base(url, handler) => _subdomain = subdomain;
public override RouteData GetRouteData(HttpContextBase httpContext)
{
string host = httpContext.Request.Headers["Host"]; // 含 port
if (host.StartsWith(_subdomain + "."))
return base.GetRouteData(httpContext);
return null;
}
}
// 註冊
routes.Add("Blog", new SubdomainRoute("blog", "{controller}/{action}/{id}", new MvcRouteHandler()));
// 1. 內建除錯:RouteDebugger (NuGet: routedebugger)
// 在瀏覽器訪問 /_debug/routes 查看所有路由匹配詳情
// 2. 單元測試路由 (Moq + MvcContrib.TestHelper)
[Test]
public void Product_Route_Matches_Correctly()
{
"~/Product/Jerseys".ShouldMapTo(c => c.Detail("Jerseys"));
"~/Product/123".ShouldNotMap(); // id 約束為字母
}
| 屬性 | 說明 |
|---|---|
Values | 路由參數字典 (controller, action, id...) |
DataTokens | 額外資料:area, namespaces, UseNamespaceFallback |
Route | 匹配的 RouteBase 實例 |
RouteHandler | IRouteHandler (通常為 MvcRouteHandler) |
Routing 是 MVC **「URL 即介面」** 的基石。掌握 MapRoute、約束、區域、子域名、測試策略,能設計出** RESTful、SEO 友善、版本可控、易於測試** 的 URL 體系。記住:**路由順序即優先序**,具體路由前置、通用路由後置,並善用 IgnoreRoute 排除靜態資源與傳統處理程式。