iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Software Development

C# ASP.NET MVC實作: 30天打造屬於你的網站應用程式系列 第 25

(DAY 25)C# ASP .NET MVC實作: 30天打造屬於你的網站應用程式-路由(Route)

  • 分享至 

  • xImage
  •  

雖然在DAY 3的時候已經介紹過路由的一些基本規範,當時我們知道ASP .NET MVC 是藉由路由(Route)規範方式將URL模式連結到Controller,且網址路由是定義在「App_Start」資料夾中的「RouteConfig.cs」檔案裡。但當時沒有說明太多,今天我們再稍微深入探討相關內容。

我們先重提一下原本預設的路由規則,如下Code:

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

這個路由規則的名稱name叫做Defaulturl的規則是Domain/控制器名稱/動作方法名稱/id參數值,輸入的網址會依此連到程式對應的控制器與動作方法。
defaults則規定了當url沒有輸入控制器名稱,預設會連到HomeController;當url少了動作方法名稱,預設會連到Index()動作方法;當url沒有id參數時沒關係,因為預設為UrlParameter.Optional,代表參數可有可無。

由上述規則得知,當輸入的網址如果是:
https://localhost:44334/Home/Index
https://localhost:44334/Home/
https://localhost:44334/
都會連結到HomeController底下的Index()動作方法。

● 自訂路由規則與比對順序

事實上路由規則可以有不只一組,比如下方Code,我在預設路由規則上面添加了一組新的路由規則,那麼會發生什麼事情呢?

            routes.MapRoute(
                name: "Test",
                url: "Index123/{controller}/{action}",
                defaults: new { controller = "Home", action = "Index" }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );

首先路由規則比對的順序是由上而下,因此輸入的url會優先比對Test這組規則,如果比對後無法符合該規則,會繼續比對下一組,也就是Default。因此假如輸入的網址如果是:
https://localhost:44334/Index123/Home/Login,它一樣會去執行HomeController底下的Login()方法。同樣道理,當網址為:
https://localhost:44334/Index123/Home/Index
https://localhost:44334/Index123/Home
https://localhost:44334/Index123/
同樣會連結到HomeController底下的Index()動作方法。

● 路由條件約束

路由規則可以加上constraints來設定條件約束,直接舉下方Code例子來說明,比方說網址列如果有id參數的話,我們除了在動作方法將它的型別設為int以外,又希望要求輸入的值應該要是正數(>0)的話可以怎麼做呢?

    public class TestController : Controller
    {
        // GET: Test
        public ActionResult ShowContent(int id)
        {
            return Content($"會員編號是: {id}");
        }
    }

針對這樣的條件需求,我們可以在路由規則上增加constraints來限制條件,如下寫法:

            routes.MapRoute(
                name: "Test",
                url: "Test/{id}",
                defaults: new { controller = "Test", action = "ShowContent" }, 
                constraints: new { id = @"\d+" }
            );

這邊利用了正規表達式(Regular Expression)來限制id參數必須為一或多個0-9整數組合的值,當id輸入負數時會顯示下圖錯誤:

● 屬性路由

除了在RouteConfig.cs設定路由規則以外,在控制器與動作方法上新增Route Attribute是另外一種限制路由的方式,要啟用屬性路由的話,必須先在RouteConfig.cs新增如下Code:

routes.MapMvcAttributeRoutes();

而且新增的位置必須於所有路由規則之前,如下圖所示:

加入後就可以在控制器上方增加[RoutePrefix()]屬性,以及在動作方法上增加[Route()]屬性。

上圖所示的[RoutePrefix("Main")]屬性表示必須有該路由前綴才能夠進入該控制器,而不是依照原本的Home
搭配[Route()][Route("Index")]表示要進入該動作方法的路由只能是Index或不加也可以。因此能夠進入此方法的url就只能是:
https://localhost:44334/Main/Index
https://localhost:44334/Main/

而以下原本的url皆無法進入:
https://localhost:44334/Home/Index
https://localhost:44334/Home/
https://localhost:44334/

● IgnoreRoute

最後稍微講一下在RouteConfig.cs最上面一行有個

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

這行意思是當路由格式為{resource}.axd/{*pathInfo}的情形下,會忽略路由比對。主要是方便相容Webform頁面可以並存於MVC專案內,詳細可以參考以下文章內容:
MVC專案routes.IgnoreRoute的實際用途

● 小結

今天比較詳細探討路由的觀念,其實相關資料我也是上網查了許多才比較清楚一點,如果有說明不正確或不完整的地方,再麻煩大神們指教了~


上一篇
(DAY 24)C# ASP .NET MVC實作: 30天打造屬於你的網站應用程式-部分檢視(Partial View)
下一篇
(DAY 26)C# ASP .NET MVC實作: 30天打造屬於你的網站應用程式-各種ActionResult
系列文
C# ASP.NET MVC實作: 30天打造屬於你的網站應用程式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言