Web API中的路由——基本路由

Posted 捞月亮的猴子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web API中的路由——基本路由相关的知识,希望对你有一定的参考价值。

 一.Web API中的路由概念

  路由的作用用一句话说明:通过request的uri找到处理该请求的Controller,Action,以及给Action的参数赋值

web api中默认的路由:

routes.MapHttpRoute(
  name: "API Default",
  routeTemplate: "api/{controller}/{id}",
  defaults: new { id = RouteParameter.Optional }
);

   route table 中的每个 route (路由规则对象)都包含一个路由模板( route template )。Web API的默认路由模板是“api / {controller} / {id}”。在此模板中,“api”是文字路径段,{controller}和{id}是占位符变量。

当Web API框架收到HTTP请求时,它会尝试将URI与route table中的某个route template进行匹配。如果没有route匹配,则客户端收到404错误。

二、路由过程

  路由的过程有三步:
    1.通过uri匹配到route template
    2.获取对应的Controller
    3.获取对应的Action

(一)通过uri匹配到route template

  路由模板看起来很像uri地址,但是它包含了一些占位符,下边我们添加一个route(路由规则),名字是MyRoute,当没有controller时,默认的controller时Home;自定义参数id添加了一个约束:id必须是数字。当我们添加下边的代码后,routetable就多了一个route对象。

config.Routes.MapHttpRoute(
  name: "DefaultApi",
  routeTemplate: "api/{controller}/{id}",
  defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
  name: "MyRoute",
  routeTemplate: "api/{controller}/{action}/{id}",
  //可以给占位符提供默认值
  defaults: new { controller = "Home" },
  //可以给占位符添加约束,只有id是数字时才匹配这个路由规则
  constraints: new { id = @"d+" }
);

  当框架接受到一个request时,会查找uri匹配的路由模板,找到路由模板后会创建一个 Route Dictionary 对象,这个对象里包含每个占位符的值,key是占位符的名字,值从uri中或者默认值中获取。这个字典对象存储在IHttpRouteData对象中。
  一个栗子:uri为api/Products/FindProduct/1,匹配成功MyRoute的routeTemplate成功,创建的路由字典中包含了

  controller:Products
  action:FindProduct
  id:1

(二)、获取Controller

Controller的默认方法很简单:
  找到路由字典中的controller,在controller的值后天追究“Controller”。如我们路由字典中的controller的值是Products,那么找的Controller就是 Products+"Controller"=ProductsController。

(三)、获取Action

  获取Action时,Web API会查看HTTP方法,然后查找名称以该HTTP方法名称开头的action。例如,对于GET请求,Web API会查找以“Get ...”开头的操作,例如“GetContact”或“GetAllContacts”。此约定仅适用于GET,POST,PUT和DELETE方法。您可以使用控制器上的属性启用其他HTTP方法。当找到多个方法符合http method时,匹配参数符合最多的那个。

三、路由变体

(一)通过属性标签 

  当我们使用[HttpGet] [HttpPost] [HttpPut] [HttpDelete]特性修饰action时,web api接收到一个请求时,也会按照http method进行查找,如用[HttpGet]修饰action,我们以get的形式访问http://xxx:xx/Products时,会找到下边栗子的FindProduct(id)。注意:如果没有属性标签,也不以Http method开头,那么默认为post。
  一个栗子:

public class ProductsController : ApiController
{
  [HttpGet]
  public Product FindProduct(int id) {}
}

(二)匹配多个Http method  

  如果我们想让一个方法在多个Http method中匹配,如我们使用get或者post请求时都访问方法FindProduct(id),怎么去设置呢?可以使用AcceptVervs进行设置,如下设置后当我们使用get或者post请求api/products/都会匹配到方法FindProduct

public class ProductsController : ApiController
{
  [AcceptVerbs("GET", "POST")]
  public Product FindProduct(id) { }
}

怎么让controller中的普通方法,不被匹配到呢?只需要在方法上边添加 [Nonaction] 即可

[NonAction]
public string GetStr(Product p){
    return p.Name;
}

 







以上是关于Web API中的路由——基本路由的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Laravel 8 中的自定义 Web 路由中删除“api/”前缀?

Web Api 属性路由中的可选参数

Web API系列教程2.1 — ASP.NET Web API中的路由机制

Web API系列教程2.2 — ASP.NET Web API中的路由和动作选择机制

弃用单个 Web API 方法上的多个路由中的特定路由

Web API 2中的多路由