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

ASP.NET MVC 學習筆記 (二) Routing 路由組件深度解析:URL 識別與分派核心

     編輯:關於ASP.NET

Routing 是 ASP.NET MVC **第一個管線環節**:將傳入 URL 解析為 {controller}, {action}, {id} 等路由值,決定請求由哪個 Controller/Action 處理。本文從基礎 MapRoute 到進階 **路由約束、區域、子域名、測試策略**,完整解析 System.Web.Routing 核心機制。

路由註冊基礎 (Global.asax)

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);
    // 其他初始化...
}

路由匹配流程

  1. 依註冊順序遍歷 RouteCollection。
  2. 以 Route.GetRouteData(HttpContextBase) 嘗試匹配請求 URL。
  3. 成功 → 回傳 RouteData (含 Values, DataTokens, Route, RouteHandler)。
  4. 失敗 → 繼續下一條路由。
  5. 全部失敗 → 404 (或交給現有檔案處理)。

進階路由功能

1. 路由約束

// 內建約束
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() }

2. 區域註冊

// 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();

3. 子域名路由

// 需自訂 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()));

4. 路由除錯與測試

// 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 約束為字母
}

RouteData 核心屬性

屬性說明
Values路由參數字典 (controller, action, id...)
DataTokens額外資料:area, namespaces, UseNamespaceFallback
Route匹配的 RouteBase 實例
RouteHandlerIRouteHandler (通常為 MvcRouteHandler)

結語

Routing 是 MVC **「URL 即介面」** 的基石。掌握 MapRoute、約束、區域、子域名、測試策略,能設計出** RESTful、SEO 友善、版本可控、易於測試** 的 URL 體系。記住:**路由順序即優先序**,具體路由前置、通用路由後置,並善用 IgnoreRoute 排除靜態資源與傳統處理程式。

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