这一篇文章描述了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方法。