【Web API系列教程】2.1 — ASP.NET Web API中的路由机制
这篇文章描述了asp.net web api如何将http请求发送(路由)到控制器。
备注:如果你对asp.net mvc很熟悉,你会发现web api路由和mvc路由非常相似。主要区别是web api使用http方法来选择动作(action),而不是uri路径。你也可以在web api中使用mvc风格的路由。这篇文章不需要asp.net mvc的任何知识。
路由表
在asp.net web api中,控制器是一个用于处理http请求的类。控制器中的公共方法被称为动作方法或简单动作。当web api框架收到请求时,它会将该请求路由到相应的动作中。
为了确定哪个动作该被执行,框架就会使用本节将讲解的路由表。visual studio的web api项目模板就创建了一个默认的路由表:
routes.maphttproute( name: "api default", routetemplate: "api/{controller}/{id}", defaults: new { id = routeparameter.optional } );
这个路由被定义在app_start目录下的wepapiconfig.cs文件中。
路由表中的每条记录都包含了一个路由模板。web api的默认路由模板是“api/{controller}/{id}”。在这个模板中,”api”是一个字面路径字段,而{controller}和{id}都是占位符变量。
当web api框架收到了http请求时,它将会尽力匹配uri到路由表中的路由模板的其中一个。如果没有路由被匹配到,客户端就会收到404错误。例如,以下uri会匹配到默认路由:
/api/contacts /api/contacts/1 /api/products/gizmo1然而,以下uri不会匹配到,因为它缺乏“api”字段。
/contacts/1
备注:在路由中使用“api”的原因是为了避免和asp.net mvc的路由冲突。也就是说,你可以使用”/contacts”匹配到mvc的路由,使用“api/contacts”匹配到web api的路由。当然了,如果你不喜欢这种约定,你也可以修改默认路由表。
一旦某个路由匹配到了,web api就会选择相应的控制器及动作:
为了找到控制器,web api将“controller”添加到{controller}变量上。 为了找到动作,web api会遍历http方法,然后查找一个其名字以http方法的名字开头的动作。例如,有一个get请求,web api会查找以“get….”开头的动作,比如”getcontact”或”getallcontacts”。这种方式仅仅适用于get、post、put和delete方法。你可以通过在你的控制器中使用属性来启用其他http方法。将晚些看到一个示例(超链接到本章的第三节…… 路由模板的其他占位符变量,比如{id},会被映射到动作的参数。让我们来看一个示例。假定你定义了如下的控制器:
public class productscontroller : apicontroller { public void getallproducts() { } public ienumerablegetproductbyid(int id) { } public httpresponsemessage deleteproduct(int id){ } }
这里是一些可能的http请求,以及相应的得到执行的动作:
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) |
注意uri的{id}字段,如果存在,它会被映射到动作的id参数中。在本例,控制器定义了两个get方法,其中一个包含id参数,而另一个不包含id参数。
同样的,注意到post请求会失败,因为控制器中并没有定义”post…”方法。
路由偏差(routing variations)
前一节描述了asp.net web api的基本路由机制。本节将开始描述一些变化。
http方法
除了使用这些http方法的命名约定,你也可以通过用httpget、httpput、httppost或httpdelete属性来赋予这些动作来具体地为每个动作设定http方法。
在下面这个例子中,findproduct方法被映射到get请求:
public class productscontroller : apicontroller { [httpget] public product findproduct(id) {} }
为了让一个动作支持多个http方法,或支持除get、put、post和delete之外的http方法,你可以使用acceptverbs属性,它以一个http方法列表为参数。
public class productscontroller : apicontroller { [acceptverbs("get", "head")] public product findproduct(id) { } // webdav method [acceptverbs("mkcol")] public void makecollection() { } }
通过动作名进行路由
有了默认的路由模板,web api使用http方法来选择动作。然而,你也可以创建一个将动作名包含在uri中的路由表。
routes.maphttproute( name: "actionapi", routetemplate: "api/{controller}/{action}/{id}", defaults: new { id = routeparameter.optional } );
在这个路由模板中,{action}参数在控制器中命名了一个动作方法。在这种风格的路由中,应使用属性来指定允许的http方法。例如,假定你的控制器有了以下方法:
public class productscontroller : apicontroller { [httpget] public string details(int id); }
在这种情况下,对于“api/products/details/1”的get请求被被映射到details方法。这种风格的路由和asp.net mvc很接近,并且可能适合于rpc风格的api。
你可以通过actionname属性来重写动作名。在接下来的例子中,存在两个都映射到”api/products/thumbnail/id”的动作。其中一个支持get,另一个支持post:
public class productscontroller : apicontroller { [httpget] [actionname("thumbnail")] public httpresponsemessage getthumbnailimage(int id); [httppost] [actionname("thumbnail")] public void addthumbnailimage(int id); }
无动作(non-actions)
为了阻止一个方法被当作动作来执行,可以使用nonaction属性。这会框架指明该方法并非一个动作,即使是它可能匹配到路由规则。
// not an action method. [nonaction] public string getprivatedata() { ... }
推荐阅读
-
【Web API系列教程】2.2 — ASP.NET Web API中的路由和动作选择机制
-
ASP.NET Web API 2系列(二):灵活多样的路由配置
-
ASP.NET Web API中的Controller
-
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程——使用Repository模式构建数据库访问层
-
使用HTTP-REPL工具测试ASP.NET Core 2.2中的WEB API项目
-
【Web API系列教程】2.3 — ASP.NET Web API 2中的属性路由
-
使用OWIN自托管开发ASP.NET Web API的系列
-
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
-
【Web API系列教程】1.3 — 实战:用ASP.NET Web API和Angular.js创建单页面应用程序(上)...
-
使用ASP.NET Web Api构建基于REST风格的服务实战系列教程【七】——实现资源的分页