[HowTo].Net Core 2.1/3.1 如何取得 Controller 指定路由的完整 Url

阿蘇卡
Aug 3, 2021

--

Photo by Danielle MacInnes on Unsplash

.Net Core 2.1 MVC 專案中,可使用 Url.Link 取得指定路由(例如:organizers/5) 的完整網址,設定方式如下:

建立專案

首先建立一個 .Net Core 2.1 版本的 MVC 專案;

再另外建立一個 OrganizersController,作為被呼叫方

功能很簡單,回傳內容是顯示接收到的 id 參數 。

使用 Url.Link 取得指定路由網址

接下來,調整內建的 ValuesController 中 Get(int id),將回傳值改為以上路由的網址,例如:api/organizers/5

使用 Url.Link 取得自動轉換 Url;

第一個參數是 routeName:為自訂的路由名稱

第二個參數類型是 object,依據路由所需參數傳遞

設定到這裡,測試會發現回傳值為 null 😲

原因是第一個參數的路由名稱,還沒有定義呢! 所以 .Net Core 不知道要如何轉換。

讓我們回到 Startup.cs 設定路由規則

設定專用慣例路由

根據一開始設定的 OrganizersController,慣例路由應該設定如下:

第一個參數 name:即 Url.Link 使用的第一個參數。

⚠️ 兩邊參數名稱要一致!

第二個參數 template:為路由的型態,由於定義的內容不帶參數(即大括號 {} 包含的名稱),因此此路由只會符合 OrganizersController.GetAction

第三個參數 default:當 template 中有 controller、action 參數時,會自動被帶入,但此次不會使用

⚠️ 慣例路由可設定多組,比對路由時會由上而下,且只會符合一個規則。
找到符合規則者就會被執行,因此記得要先放置明確的的路由。

以上設定完後,就可以取得 url 囉,本機測試會取得網址應類似如下:

https://localhost:44398/api/organizers/8

[補充] .NetCore 2.2 使用注意事項

如果你的專案版本是 .Net Core 2.2,會發現做完以上設定,Url.Link 回傳的是 null 😭

因為 .Net Core 2.2 版本後,引入了 EndpointRouting,將 Url 與 Action 關聯從 mvc 中抽離,成為獨立的 Middleware。

因此,先前在 UseMvc 中設定的 MapRoute 就沒有作用了。

解決方法有兩種,依照專案性質做選擇:

解法一. 設定相容版本

這個解法最簡單,只要將 ConfigureServices 中設定

services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

改成

services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

解法二. 關閉 EndpointRouting

如果專案中沒有透過 Middleware 取得 action 資料再處理的話,也可以採取此方法,設定方式一樣是在 ConfigureServices:

services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

改為

services.AddMvc(config =>
{
config.EnableEndpointRouting = false;
}).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

參考資料:何謂慣例路由

完整專案範例:Github

以上內容希望對各位有幫助
有任何建議歡迎留言

--

--

阿蘇卡
阿蘇卡

Written by 阿蘇卡

後端工程師。記錄下自己開發路上踩過的坑、研究過後的心得,希望對自己好,對其他工程師也好~

No responses yet