ASP.NET Core 中使用UseRouting()
和UseEndpoints()
這兩個Middleware來比對傳入請求的URL,並將這些請求對應到Controller中的Action。
若想要自定義Middleware的順序,我們可以在Program.cs
中明確定義這兩個Middleware。如果沒有定義也沒關係,ASP.NET Core預設會在Pipeline(管線)中自動加入這兩個Middleware。
ASP.NET Core中的路由可以分為慣例路由(Conventional routing)和屬性路由(Attribute routing),慣例路由通常用在Controller和View,屬性路由通常用在REST API,這篇筆記記錄屬性路由的相關設定。
屬性路由 Attribute routing
要讓屬性路由可以順利運作,首先必須在Program.cs
中加入MapControllers()
方法,MapControllers
用於對映所有使用屬性路由的Action。
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();//使用AddControllers讓屬性路由可以運作
var app = builder.Build();
app.MapControllers();//使用MapControllers讓屬性路由可以運作
app.Run();
屬性路由聽名字就知道跟屬性(Attribute,也就是常常會看到掛在方法或類別上方用中括號包起來的那個東西)肯定脫不了關係。
我們在開API時,會需要指定這支API的HTTP動詞及路由,ASP.NET Core 提供以下這幾個Attribute讓我們可以直接把這個屬性掛在類別或方法上方,指定其HTTP動詞或路由。
HTTP動詞Attribute
[HttpGet]
[HttpPost]
[HttpPut]
[HttpDelete]
[HttpHead]
[HttpPatch]
HTTP路由Attribute
[Route]
[ApiController]
public class BarController : ControllerBase
{
[HttpGet]
[Route("/api/Bar/List")]
public IActionResult GetBarList()
{
return Ok();
}
}
在上述範例中,GetBarList()
方法上方掛了兩個Attribute,分別是[HttpGet]
和[Route]
。當我們對這個應用程式發出方法為GET且Endpoint為/api/Bar/List
時就會執行GetBarList()
這個方法。我們可以針對不同需求使用不同的HTTP動詞搭配不同的路由建立自己需要的API。
提取重複的路由
在同一個Controller中,如果有多個Action都有使用到部分相同的路由時,可以把相同的部分提取出來,一樣使用[Route]
attribute掛到class上。
[ApiController]
[Route("/api/Bar")]
public class BarController : ControllerBase
{
//HTTP動詞與路由為:GET /api/Bar/List
[HttpGet]
[Route("List")]
public IActionResult GetBarList()
{
return Ok();
}
//HTTP動詞與路由為:GET /api/Bar/:barId
[HttpGet]
[Route("{barId}")]
public IActionResult GetBar(Guid barId)
{
return Ok();
}
//HTTP動詞與路由為:POST /api/Bar
[HttpPost]
public IActionResult PostBar()
{
return Ok();
}
}
語彙基元取代 Token replacement
這個正著唸或倒著唸都不明所以的東東在路由中可是很有用的。通常我們的路由跟Controller的類別名稱有很大的關係,如果想要直接把Controller名稱加入到路由中,我們可以在路由中使用[controller]
作為替代Controller名稱的符號。
[ApiController]
[Route("/api/[controller]")]//使用[controller]作為代替Controller名稱的符號,[controller]將會被替換為Bar(Controller的類別名稱)
public class BarController : ControllerBase
{
//HTTP動詞與路由為:GET /api/Bar/List
[HttpGet]
[Route("List")]
public IActionResult GetBarList()
{
return Ok();
}
//HTTP動詞與路由為:GET /api/Bar/:barId
[HttpGet]
[Route("{barId}")]
public IActionResult GetBar(Guid barId)
{
return Ok();
}
//HTTP動詞與路由為:POST /api/Bar
[HttpPost]
public IActionResult PostBar()
{
return Ok();
}
}
除了[controller]
,ASP.NET Core還提供另外兩個token,分別是[area]
和[action]
。
[area]
會被自動替換為Area的名稱,而[action]
則會被替換為controller內action的名稱。
多個屬性路由
我們可以使用多個屬性路由指向同一個Controller或Action,常見的用法是用在「預設慣例路由」,也可以用在任何想要把一個以上的路由對應到同一個Controller或Action時。
[ApiController]
[Route("/api/Foo")]
[Route("/api/[controller]")]
// 「/api/Foo」和「/api/Bar」都會指向這個Controller
public class BarController : ControllerBase
{
[HttpGet]
[Route("")]
[Route("List")]
// 「/api/Foo」、「/api/Bar」、「/api/Foo/List」、「/api/Bar/List」都會指向這個Action
public IActionResult GetBarList()
{
return Ok();
}
}
多個HTTP動詞Attribute
除了可以在掛上多個屬性路由,還可以掛多個HTTP動詞Attribute,不過非必要通常不建議這樣做,除非為了支援舊版API之類的非必要情況,否則可能會難以維護。