進度條

[C#][.Net MVC] 03. MVC下的URL Route 設定

說到MVC網站就不能不提到Route設定!

作者: Toyo 更新日期:

什麼是Route? 在現實生活中比較接近於郵差與地圖的關係,你將想要送的東西交給郵差,郵差依據包裹上的地址,透過地圖找到目的地然後投遞。

 

而對應到程式中[網址]就是你包裹要送達的目的地址,Route就是[地圖],而網址的[參數]就是你要投遞的包裹。

 

 

接著我們來看看專案內的Route在哪邊設定,又它是如何透過網址知道該把[包裹]送去哪支程式的,這邊先把我們之前的專案執行起來,並且點擊[關於]

 

 

可以看到關於頁的網址為 /Home/About

 

 

 

接著我們在HomeController的About下中斷點後再點擊一次網頁的[關於]按鈕,會發現程式停在我們下中斷點的地方了? 為什麼知道程式會跑到這邊呢 ? 

這一切都是因為有Route指路的關係

 

 

RouteConfig

Route的規則是可以自己制訂的,而制定的地方就在App_Start資料夾底下的RouteConfig裡面

 

 

 

 

 

讓我們來解讀這段程式碼,首先routes.MapRoute就是註冊地址的方法,裡面有幾個參數分別為

Name : 你對於這個Route的命名

Url : 網址條件,當網址符合這個條件特徵時,就會依據這個Route的指示去找對應執行的程式碼

defaults : 參數的預設值

 


相信光是講解參數的意義對於要理解Route還有相當的距離,讓我們直接來實戰理解 /Home/About這串網址如何對應到Route的吧,剛剛有說, routes.MapRoute的Url參數是用來判斷網址特徵是否相符,如果相符就會被這串Route捕捉到,但是這兩個怎麼看都不像啊!

 

真實網址 : /Home/About

Route Url :  {controller}/{action}/{id}

 

首先必須先知道一件事情,當Route Url的網址用{ }包起來的時候,代表他是個變數,什麼是變數?

變數是一個表示值,它可以是任意的值,而{}裡面的字就是變數的名稱,以上述例子為例

我們有一個變數叫做controller,它可以是任意的值

我們有一個變數叫做action,它可以是任意得值

我們有一個變數叫做id,它也可以是任意的值

那套入/Home/About會變成什麼結果?

 

 

我們有一個變數叫做controller,它現在的值是Home

我們有一個變數叫做action,它現在的值是About

我們有一個變數叫做id,它現在沒有值

 

而Route的制定中,controller跟action為保留字,意思是告訴他要執行哪個controller跟Action,依據這邊的規定,所以它知道要去執行Home這個Controller,裡面一個叫做About的Action。

 

 

[編按: 在Controller裡面寫的方法我們稱之為Action,而他通常都會回傳ActionResult]

再讓我們看一個例子 : [首頁]

首頁的網址為 : http://localhost:54004/

 

編按 :網址最前面這段寫著 Localhost :54004 ,Localhost為網址的Domain,54004為Port,domain 是網站的位置,例如我們在google搜尋Facebook時,會看到網址變成

https://www.google.com.tw/search?q=facebook

而www.google.com.tw就是Domain,當讀到這串Domain時,就會透DNS找到Google的伺服器,然後呼叫它,並且請求他執行/search?q=facebook,這也是為什麼我們討論Route時沒有把Domain納進來,Domain只是讓網路能找到你服務的伺服器位置,後面才是你撰寫程式要處理的Route網址

 

 

所以首頁網址等於

首頁網址 : /

Route Url :  {controller}/{action}/{id}

 

我們有一個變數叫做controller,它現在沒有值

我們有一個變數叫做action,它現在沒有值

我們有一個變數叫做id,它現在沒有值

 


什麼都沒有,那程式到底要執行哪邊? 這時候Default終於派上用場了,Default的意思就是,當沒有值

時,請用我設定的值代替吧

 

 


所以

controller為空值,所以用Default的值代替,所以它的值為Home

action為空值,所以用Default的值代替,所以它的值為Index

id為空值,但Default設定它為UrlParameter.Optional,意思是它是選擇性的,如果沒有沒關係。

 

所以這個Route設定又完美符合了,所以依據條件,我們去HomeController的Index下中斷點,試試看進入首頁時是不是會停在這邊

 

 

的確,他依據規則跑到了HomeController的Index Action了。

那舉一反三一下,換句話說首頁網址也可以是 /Home/Index 摟,試試看,你會發現它的確走到一樣的中斷點

 

 

你可能會說,那這樣Route還有什麼好學的,這個寫法幾乎萬用了啊? 的確在MVC預設專案中的這個Route設定我們通常稱它為萬用Route,但也因為它幾乎萬用,所以不好管理,所以正常來說都還是會制定自己的Route規則,好方便管理,這個之後慢慢寫專案碰到多了會更有感觸。

 

接著我們來試著修改一下程式,讓我們的{id}能派上用場吧!!

在剛剛的案例中,因為id設定是Optional所以都沒派上用場,來試試看他怎麼用吧,首先我們先在 HomeController 的 About Action中加入參數 id,並且把回傳的訊息改成 Your id is (你帶進來的值)

 

 

接著我們重新執行一次程式,並且把網址改成/Home/About/Steven

 

 

再練習一次Route比對

 

我們有一個變數叫做controller,它現在的值是Home

我們有一個變數叫做action,它現在的值是About

我們有一個變數叫做id,它現在的值是Steven

 

讓接著看中斷點,把滑鼠移到id那的參數會看到,Id依據我們下的網址,以Steven帶進來了

 

 

接著看網頁呈現的成果

 

 

練習制定一個屬於我們的Route

看了兩個範例,我們也來制定一個Route規則給自己用吧,而且我們不要用變數的方式。

 

 


我們希望有個網址為/tellMe/whoAreYou/{name},且name跟之前的id一樣是個變數,可以由你自己打

喜歡的文字來決定,寫完後來試試看這個route可不可行

 

 

結果竟然錯了,來看看少了什麼

 

網址 : /tellMe/whoAreYou/steven

Route Url :  /tellMe/whoAreYou/{name}

 

 

比對tellMe,符合

比對whoAreYou,符合

比對Name這個變數,現在的值為Steve

然後呢? 有沒有發現即便這邊都比對正確,符合route規則,但我們沒告訴他Controller是誰,Action是

誰,程式當然不知道該去執行誰,所以再來改一下,因為我們還沒學到如何建立Controller跟Action,

所以先用現成的, 導到homeController的Contact吧!

 

 

 

讓我們再試試看剛剛的網址

 

 

這次不會壞掉了,且正確的導到HomeController的Contact Action去,接著試試不帶{Name}會怎麼樣

 

變成找不到資源,為什麼?因為我們的Name沒有設定 UrlParameter.Optional,所以是必帶的參數,這邊要特別注意!!! 之前教很多新人Route時很多人都卡在這邊

 

Route比對時必須完全符合才會被捕捉到

 

所以回頭審視我們的Route註冊目前有兩個規則

  1. tellMe/whoAreYou/{name}
  2. {controller}/{action}/{id}

 

而我們帶的網址為 /tellMe/whoAreYou ,比對的規則將會是

由上到下,所以先比對了 1. tellMe/whoAreYou/{name} 的規則 

tellMe,符合

whoAreYou,符合

Route要求要有Name,且不是Optional,所以必帶,不符合

 

 

這段Route會被跳過,執行比對2. {controller}/{action}/{id}的規則

Controller為tellMe,符合

Action為WhoAreYou,符合

Id為空值,因為為Optional,符合

 

所以實際程式去找的是TellMeController裡面的WhoAreYou這個Action,因為找不到這支程式所以顯示錯誤,而不是去執行規則1. 的 HomeController 的Contact這個Action。

 

這是新手常常會犯的觀念錯誤,所以特別舉這個例子希望能夠較清楚的比較跟釐清,而Route因為還有很多種設定,避免一次太多造成混亂,所以先到這邊。試著將上述的觀念釐清,對於之後撰寫MVCRoute時會很有幫助

 

 


最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!

Medium 0

Toyo

年過30在軟體業載浮載沉的工程師, 期望靠著一點一滴累積與努力, 讓自己墊起腳能勾到一點點的夢想