iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 6
1

前言

網站伺服器大多都是透過URL方式作為進入點,
因此對路由的解析就變得格外重要,
本篇將介紹ASP.Net Core 路由的設定方式。

同步發表於個人點部落 - [鐵人賽Day06] ASP.Net Core MVC 進化之路 - 路由(Route)

Route

ASP.Net MVC5的專案中,
如果要針對路由進行設定,
我們會針對App_Start底下的檔案進行設定。
MVC的話會對應到RouteConfig.cs
WebApi則使用WebApiConfig.cs進行設定。

ASP.Net Core中統一將路由(Route)以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(就是可給可不給)。

區域性的路由設定沿用原本的[Route]Attribute,
在優序上[Route]大於在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?}");

    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之外,
還有MapGetMapPostMapPutMapDelete等用法。
設定完路由規則後記得呼叫**Build()**建立IRouter物件(它才是真正的路由),
並將路由加入到應用程式中。

請記得一個IRouter可能包含多項路由規則,
路由規則的先後順序將影響執行的結果,
所以設定時請記得將優序較高的路由放在前面,
並避免設計模稜兩可的路由規則。

路由的規則就簡單記錄到這邊,
如果有內容不正確的地方麻煩各位大神指正,
下一篇會介紹URL RedirectURL Rewriter的用法及差別。


上一篇
[鐵人賽Day05] - 靜態檔案(Static Files)
下一篇
[鐵人賽Day07] - URL複寫(URL Rewrite)
系列文
菜鳥練等區-ASP.Net Core MVC進化之路30

尚未有邦友留言

立即登入留言