感覺Routing的東西比較有意思,就把微軟官方的教程簡單翻譯一下放在這裏。
- WebAPI 的routing 與MVC不同
WebAPI | MVC |
---|---|
Httpmethod | URL Path |
- Routing talbe
WebAPI裏面,controller類處理HTTP request。只有聲明爲public的方法才被成爲Action Method 或者 Simple Method.
Route 定義在WebApiConfig.cs文件中,文件保存在 App_Start文件夾中。
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
針對上面定義的route,下面的幾個URL可以匹配到:
/api/contacts
/api/contacts/1
/api/products/gizmo1
但是,下面的RUL無法匹配,因爲缺少了api部分:
/contacts/1
所以,其實api是一個語法文字路徑段, {controller} 和{id} 是變量段。
一旦匹配成功,WebAPI選擇controller和action的過程如下:
1. 尋找controller, WebAPI將在匹配到的{controller} 變量值後面加上”Controller”來定位到具體的controller。
2. 尋找action,WebAPI會尋找HTTP Method,或者以HTTP Method名稱開頭的Method。例如,對於一個GET的方法,WebAPI將會尋找以’Get’開頭的方法,例如”GetContact” or “GetAllContacts”。但是這種轉換僅針對 GET, POST, PUT, and DELETE 方法。你在方法前定義其他的HTTP Methods。
3. 其他預留的變量,例如{id},將會與方法的參數進行匹配。
舉個栗子:
public class ProductsController : ApiController
{
public void GetAllProducts() { }
public IEnumerable<Product> GetProductById(int id) { }
public HttpResponseMessage DeleteProduct(int id){ }
}
下面是一個比對錶
ked for each:
HTTP Method | URI Path | Action | Parameter |
---|---|---|---|
GET | api/products | GetAllProducts | (none) |
GET | api/products/4 | GetProductById 4 | |
DELETE | api/products/4 | DeleteProduct 4 | |
POST | api/products | (no match) |
注意,對於{id},如果出現在RUL中,那WebAPI就會調用帶id參數的方法。
- HTTP Methods
可以在一些方法前面顯示的定義HTTP Methods, 使得不以HTTP Method關鍵字開頭的方法也可以定義爲HTTP Method。
public class ProductsController : ApiController
{
[HttpGet]
public Product FindProduct(id) {}
}
如果想允許一個方法有多個HTTP Method,或者定義除了GET, PUT, POST, and DELETE意外的HTTP Method,可以在方法前面加AcceptVerbs屬性來定義HTTP Method,例如
public class ProductsController : ApiController
{
[AcceptVerbs("GET", "HEAD")]
public Product FindProduct(id) { }
// WebDAV method
[AcceptVerbs("MKCOL")]
public void MakeCollection() { }
}
上面兩個方法分別可以用HEAD和MKCOL引用。
- Routing by Action Name
public class ProductsController : ApiController
{
[HttpGet]
[ActionName("Thumbnail")]
public HttpResponseMessage GetThumbnailImage(int id);
[HttpPost]
[ActionName("Thumbnail")]
public void AddThumbnailImage(int id);
}
上面的兩個方法都可以匹配”api/products/thumbnail/id”,只不過一個是GET請求,一個是POST請求。
- Non-Actions
如果爲了防止一個方法在一個action中被調用,可以在方法前面加NonAction 屬性,即使這個方法名在路徑中被匹配到了也不會執行。
`
// Not an action method.
[NonAction]
public string GetPrivateData() { ... }
`