屬性路由示例
今天討論 ASP.NETCoreMVC 中的屬性路由
在Startup.cs中使用UseMvc()方法:請注意,我們使用UseMvc()
方法,所以不包含默認路由模板,無法進行參數傳遞
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseMvc(); }
使用屬性路由,我們使用Route()
屬性來定義路由。我們可以在Controller
或 Controller 的操作方法上應用Route
屬性。
public class DepartmentController : Controller { [Route("")] [Route("Department")] [Route("Department/List")] public string List() { return "你好,我是list"; } public string Infor() { return "你好,我是infor"; } }
在List()
操作方法上指定了 3 個不同的Route()
屬性。對於Route()
屬性的每個實例,我們指定了不同的路由模板。使用這 3 個路由模板,3 個 URL 路徑中,都會訪問 DepartmentController的 List()操作方法。
使用這 3 個路由模板,當遇到以下 3 種 url 地址進行訪問DepartmentController的List()
操作方法的時候,都會匹配成功,進入方法內。
屬性路由參數
使用傳統路由,我們可以將路由參數指定為路由模板的一部分,比如,在Index()中傳一個主鍵等等。 當然屬性路由也可以做同樣的事情。
public class DepartmentController : Controller { private readonly IStudentRepository _studentRepository; //使用構造函數注入的方式注入IStudentRepository
public DepartmentController(IStudentRepository studentRepository) { _studentRepository = studentRepository; } [Route("Home/Details/{id}")] public IActionResult Details(int id) { //實例化HomeDetailsViewModel並存儲Student詳細信息和PageTitle
HomeDetailsViewModel homeDetailsViewModel = new HomeDetailsViewModel() { Student = _studentRepository.GetStudent(id), PageTitle = "學生詳細信息" }; return View(homeDetailsViewModel); } }
Details ()
操作方法具有 id
參數。此參數根據指定的 id 來查詢學生的詳細信息 。請注意, 在路由模板中, 我們指定了 id
參數。因此, URL (/Department/Details)
將執行Details (int id)
操作方法, 並將值"1"映射到Details(int id)
的"id"參數
屬性路由可選參數
當前,當我們在URL(/ Department/ Details / 1)
中具有“id”路由參數的值時,才執行DepartmentController
的Details(int id)
操作方法。 如果 id 值不在 URL 中,我們得到 404. 例如,URl / Department/ Details
不會執行Details(int id)
操作方法。 而是顯示 404 錯誤。 要使路由參數“id”可選,只需在末尾添加“?” 即可。
public class DepartmentController : Controller { private readonly IStudentRepository _studentRepository; //使用構造函數注入的方式注入IStudentRepository
public DepartmentController(IStudentRepository studentRepository) { _studentRepository = studentRepository; } [Route("Home/Details/{id?}")] public IActionResult Details(int id) { //實例化HomeDetailsViewModel並存儲Student詳細信息和PageTitle
HomeDetailsViewModel homeDetailsViewModel = new HomeDetailsViewModel() { Student = _studentRepository.GetStudent(id), PageTitle = "學生詳細信息" }; return View(homeDetailsViewModel); } }
控制器和操作方法名稱
在屬性路由中,控制器名稱和操作方法名稱,不會影響路由屬性名稱,他們沒有強關聯關系。 路徑名稱我們自己定義,然后根據自己的定義進行查找對應的控制器和方法。
public class DepartmentController : Controller { [Route("")] [Route("Home")] [Route("Home/Index")] public ViewResult Department() { return View(); } }
通過以下三種方式依然可以查找到:
/
/Home /Home/Index
屬性路由支持層次結構
在 HomeController
類上應用Route()屬性
,如下所示。主要降低代碼重復
namespace StudentManagement.Controllers { [Route("Department")] public class DepartmentController : Controller { [Route("/")] [Route("List")] public string List() { return "你好,我是list"; } [Route("Infor/{id}")] public string Infor(int id) { return "你好,我是infor"; } } }
這樣,項目啟動,就會直接找到Department控制器下的List方法,如果[Route("/")]中不加斜杠,直接啟動項目會報錯,說找不到頁面,需要帶上控制器名稱才能找到,加上的話直接啟動就會找到
屬性路由中自定義路由
[Route("[controller]")] public class DepartmentController : Controller { [Route("[action]")] public string List() { return " DepartmentController控制器中的List()方法"; } [Route("[action]")] public string Details() { return " DepartmentController控制器中的Details()方法"; } }
使用 controller 和 action 標記,在 URL 路徑中的/Departments/List
將進入DepartmentsController中執行List()
方法。 類似地,在 URL 路徑中的/ Departments / Details
將進入DepartmentsController中執行Details()
方法。如果我們要進行重命名控制器或動作名稱,我們就不必更改路徑模板。
要使 List()
方法成為 DepartmentController
的默認路由入口,可以使用空字符串包含的 Route(“”)
屬性,如下所示。
[Route("[controller]")] public class DepartmentController : Controller { [Route("[action]")] [Route("")] // 使 List()成為默認路由入口
public string List() { return " DepartmentController控制器中的List()方法"; } [Route("[action]")] public string Details() { return " DepartmentController控制器中的Details()方法"; } }
我們最好在控制器上只設置一次,而不是在控制器中的每個操作方法中包含[action]
標記,如下所示
[Route("[controller]/[action]")] public class DepartmentController : Controller { public string List() { return " DepartmentController控制器中的List()方法"; } }
這樣減少代碼重復。