[鐵人賽Day06] ASP.Net Core MVC 進化之路 - 路由(Route)

網站伺服器大多都是透過URL方式作為進入點,

因此對路由的解析就變得格外重要,

本篇將介紹ASP.Net Core 路由的設定方式。

 

ASP.Net MVC5的專案中,

如果要針對路由進行設定,

我們會針對App_Start底下的檔案進行設定。

MVC的話會對應到RouteConfig.cs。

WebApi則使用WebApiConfig.cs進行設定。

 

ASP.Net Core中統一將路由(Routing)Middleware的形式進行包裝,

我們可以在Startup中指定MVC全域性的預設路由。

//app.UseMvcWithDefaultRoute();
app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

上面這兩個方式實際執行的結果是一樣的,

如果不需要特別修改的話可以使用上方的UseMvcDefaultRoute()即可。

但如果想修改細部內容的話可使用第二個方式進行調整。

routes.MapRoute()

name表式這條路由規則的名稱(只是名字而已啦),

路由的規則會定義在template

controlleraction後面加等號(=)表示預設的值,

id後面加個問號(?)則表optional(就是可給可不給)。

 

區域性的路由設定沿用原本的RouteAttribute

在優序上RouteAttribute大於Startup中的MapRoute

Route裡面字串使用中括號[]可使用保留字(ControllerAction),

路由會按照該ControllerAction名稱自動對應。

[Route("MyHome/[Action]")]
public class HomeController : Controller
{
    public IActionResult Index()
    {
        return View();
    }

    public IActionResult About()
    {
        ViewData["Message"] = "Your application description page.";

        return View();
    }

    [Route("SubContact")]
    public IActionResult Contact()
    {
        ViewData["Message"] = "Your contact page.";

        return View();
    }
}

輸入https://localhost:44363/Home/Index:失敗(404)
輸入https://localhost:44363/MyHome/Index:成功(200)
輸入https://localhost:44363/MyHome/Contact:失敗(404)
輸入https://localhost:44363/MyHome/SubContact:失敗(404)
輸入https://localhost:44363/MyHome/Contact/SubContact:成功(200)

要特別注意的是,

Action裡面的路由階層,

會從Controller上定義的路由繼續向下延伸,

所以輸入https://localhost:44363/MyHome/Contact/SubContact才會對到HomeControllerContact。

另外,如果Controller層未指定Action路由,

只要其中一個Action有掛上RouteAttribute,

其他的都要跟著掛,

否則會顯示找不到頁面。

 

講完MVC的路由我們來談一下一般的路由設定,

在前面Middleware介紹中有提及了Map的簡單應用,

但更進階的操作還是使用Route Middleware會輕易些。

Route MiddlewareRouteHandlerRouteBuilder組成,

RouteHandler僅在路由規則成立後才會被呼叫,

RouteBuilder則在建立路由規則群組。

程式碼如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    var routeHandler = new RouteHandler(context =>
    {
        var routeValues = context.GetRouteData().Values;
        return context.Response.WriteAsync(
            $"My Custom Route values: {string.Join(", ", routeValues)}");
    });

    var routeBuilder = new RouteBuilder(app, routeHandler);

    routeBuilder.MapRoute(
        "Blog Country Route",
        "blog/{country:regex(^(taiwan|jopan|korea)$)}/{id:int?}");
    // 感謝網友__吳宗澤__提醒,regex 語法這邊有勘誤,已修正完畢~

    routeBuilder.MapGet("hello/{name}", context =>
    {
        var name = context.GetRouteValue("name");
        return context.Response.WriteAsync($"Hi, {name}!");
    });

    var myCustomRoute = routeBuilder.Build();
    app.UseRouter(myCustomRoute);
}

RouteBuilder支援正規表達式(Regular Expression),

也可以指定參數的型別(問號代表該參數可有可無),

除了MapRoute之外,

還有MapGet、MapPost、MapPut、MapDelete等用法。

設定完路由規則後記得呼叫Build()建立IRouter物件(它才是真正的路由),

並將路由加入到應用程式中。

 

請記得一個IRouter可能包含多項路由規則,

路由規則的先後順序將影響執行的結果,

所以設定時請記得將優序較高的路由放在前面,

並避免設計模稜兩可的路由規則。

 

路由的規則就簡單記錄到這邊,

如果有內容不正確的地方麻煩各路大神指正,

下一篇會介紹URL RedirectURL Rewriter的用法及差別。