這一篇文章描述了ASP.NET API如何將HTTP請求路由到控制器。web
若是你熟悉ASP.NET MVC,Web API路由和MVC路由很是類似,主要的不一樣地方是Web API使用HTTP方法,而不是URI路徑去選擇action。你也可以在WebAPI中使用MVC風格的路由,這一篇文章不討論任何有關MVC的知識。api
路由表:框架
在ASP.NET Web API 中,一個控制器是一個處理HTTP請求的類,Controller中的公共方法稱做action方法或者簡單方法,當Web API框架接收到一個請求,框架將請求路由到一個action。asp.net
Web API框架使用路由表(route table)來決定哪個action被調用。VS的Web API 項目模版建立了一個默認的路由模版:spa
routes.MapHttpRoute( name: "API Default", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } );
這個路由模版定義在 App_Start目錄下的WebApiConfig.cs文件中。更多關於WebApiConfig的信息 能夠看:Configuring ASP.NET Web API ..net
若是使用自寄宿(self-host)的Web API,必須經過HttpSelfHostConfiguration本身設置路由表,更多信息能夠參考:Self-Host a Web API.code
路由表中的每一個條目包含一個模板,默認的Web API路由模版是「api/{controller}/{id}」。這個模版裏,「api」是一個純文本路徑段,{controller}和{id}是佔位符(參數變量)。當Web API框架接收到一個請求時,嘗試將URI與路由表中的項(路由模版)匹配,若是沒有能夠匹配的路由項,則返回一個404錯誤,好比下面三個uri能夠和默認的路由模版進行匹配。blog
/api/contactsci
/api/contacts/1路由
/api/products/gizmo1
可是/contacts/1這個就匹配不了由於缺乏「api"段。
注:Web API 路由模版使用「api」開頭是爲了不與MVC的路由模版衝突,這樣你可以使用"/contacts"URI去路由到一個MVC controller,而使用"api/contacts" 路由到一個Web API controller。固然,若是你不喜歡,能夠修改默認的路由模版。
一旦找到匹配的路由,Web API則進行controller和action的選擇:
--To find the controller, Web API adds "Controller" to the value of the {controller} variable.
--匹配action,Web API 查看本次HTTP 方法,好比:若是是GET方法,則在controller中查找Get開頭的方法,這種查詢以HTTP請求方式開頭的action的方式只適合GET , POST , PUT 和 DELETE 方式Http請求???,你能夠經過爲action添加標識屬性的方法來指定action可匹配的HTTP請求方式以及容許其餘的HTTP請求方式。
--其餘的路由模版中的佔位符變量,好比{id},映射爲一個action參數。
下面看一個例子:定義一個以下的controller
public class ProductsController : ApiController { public void GetAllProducts() { } public IEnumerable<Product> GetProductById(int id) { } public HttpResponseMessage DeleteProduct(int id){ } }
下面表格展現了不一樣的URI所調用的action
HTTP Method |
URI Path |
Action |
參數 |
GET |
api/products |
GetAllProducts |
無 |
GET |
api/products/4 |
GetProductById |
4 |
DELETE |
api/products/4 |
DeleteProduct |
4 |
POST |
api/products |
沒有匹配的action |
|
注意:這裏的{id}段,若是指定了{id}的值,則調用有id參數的action方法 GetProductById。
由於沒有定義Post開頭的aciton方法,因此POST方式的請求找不到匹配的action。
路由拓展
--使用Http Methods 標識屬性:除了定義以HTTP請求方式開頭的action方法外,咱們可使用HttpGet , HttpPut , HttpPost 或者 HttpDelete標識屬性來指定一個action方法匹配的HTTP請求方式(與使用HTTP請求方式開頭的方法名效果同樣),例如,下面這個方法能夠和GET請求方式的HTTP請求匹配。
public class ProductsController : ApiController { [HttpGet] public Product FindProduct(id) {} }
若是一個action方法須要匹配多種HTTP請求方式,或者須要匹配除GET,POST,PUT,DELETE請求方式外的其餘請求,可使用AccptVerbs標識屬性。例如:FindProduct方法能夠同時匹配 GET 和 HEAD請求。
public class ProductsController : ApiController { [AcceptVerbs("GET", "HEAD")] public Product FindProduct(id) { } // WebDAV method [AcceptVerbs("MKCOL")] public void MakeCollection() { } }
--使用MVC風格的路由
定義路由模版:
routes.MapHttpRoute( name: "ActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } );
在這個路由模版中,{action}參數指定controller中的action的名稱,使用這種風格的路由,須要使用標識屬性指定action容許匹配的HTTP請求方式,好比:必須使用[HttpGet]、[HttpPost]等標識屬性。
public class ProductsController : ApiController { [HttpGet] public string Details(int id); }
上面的例子中一個「api/products/details/1」的GET請求,將映射到Details方法。這種風格很像MVC,可能更適合用在一個RPC-style API中。
--使用ActionName屬性定義action的別名:
public class ProductsController : ApiController { [HttpGet] [ActionName("Thumbnail")] public HttpResponseMessage GetThumbnailImage(int id); [HttpPost] [ActionName("Thumbnail")] public void AddThumbnailImage(int id); }
咱們能夠發送uri爲 "api/products/thumbnail/id"的GET請求 map to GetThumbnailImage方法。
發送uri爲"api/products/thumbnail/id"的POST請求 map to AddThumbnailImage 方法。
經過上面幾個例子能夠看出,可使用標識屬性,配置一個action方法用做匹配路由的名稱和方法。
--使用[NonAction]標識屬性來指定一個方法不爲action方法。