感觉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() { ... }
`