zoukankan      html  css  js  c++  java
  • Web API中的路由(一)——约定路由

     一.Web API中的路由概念

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

    一些路由的基本概念:

          route:路由规则对象,存放了路由的规则;
        routeCollection:路由规则集合,存放了route对象;
        route template:路由模板,形式和uri接近,用于匹配uri;
        route dictionary:路由字典,找到uri匹配的route template后创建的用于存储route template中占位符值的字典;
        RouteData:真正存放路由信息的对象,保存了Controller、Action的值等;
        Http method:请求api的方式,如get/post/put/delete等。

    web api中默认的路由:

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

       route collection 中的每个 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地址,但是它包含了一些占位符,下边我们通过 WebApiConfig.cs 添加一个route(路由规则),名字是MyRoute,当没有controller时,默认的controller时Home;自定义参数id添加了一个约束:id必须是数字。当我们添加下边的代码后,routeCollection就多了一个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时,匹配参数符合最多的那个。

    三、覆盖默认HttpMethod

    3.1  使用HttpMethod特性 

      当我们使用[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) {}
    }

    3.2  使用AcceptVerbs和NonAction特性 

      如果我们想让一个方法在多个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;
    }

    小结:以http://xxxx:xx/Products/1 简单说明webapi中路由过程:我们设定的 Route 都存放的RouteCollection中,当webapi框架到一条request后,通过request的 uri (采用的方法是 routes.MapRoute )匹配route中的 route template ,如果有匹配的话,生成一个 Route Dictionary 对象,这个字典对象中存储了route template的占位符的值;接下来我们从route dictionary中查找controller值(Products),通过字符串拼接找到处理请求的ProductsController;通过request的 http method (如这里采用的get方法),查找ProductsController中的Action中匹配get的,这时我们找到了GetAllProducts和GetProduct(int id),因为我们传入有额外的项1,在GetProduct匹配的参数1个,而在GetAllProducts中匹配的参数时0个,按匹配参数最多的进行匹配所有最终匹配的action是GetProduct,最后把额外的1赋值给GetProduct的参数id。一次路由到这里就结束了。

  • 相关阅读:
    java使用AES加密解密 AES-128-ECB加密
    快速集成iOS基于RTMP的视频推流
    iOS视频直播初窥:高仿<喵播APP>
    直播相关的开源库/项目
    iOS 常见 Crash 及解决方案
    命名规范
    实现UITableView循环利用
    最快让你上手ReactiveCocoa之进阶篇
    最快让你上手ReactiveCocoa之基础篇
    带你走进脚本世界,ijkplayer之【init-ios.sh】脚本分析
  • 原文地址:https://www.cnblogs.com/wyy1234/p/9470198.html
Copyright © 2011-2022 走看看