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:
第二步:获取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。一次路由到这里就结束了。
Web API中的路由(一)——约定路由的更多相关文章
- 【ASP.NET Web API教程】4.1 ASP.NET Web API中的路由
原文:[ASP.NET Web API教程]4.1 ASP.NET Web API中的路由 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的内容. ...
- ASP.NET Web API中的Routing(路由)
[译]Routing in ASP.NET Web API 单击此处查看原文 本文阐述了ASP.NET Web API是如何将HTTP requests路由到controllers的. 如果你对ASP ...
- Web API中的路由(二)——属性路由
一.属性路由的概念 路由让webapi将一个uri匹配到对应的action,Web API 2支持一种新类型的路由:属性路由.顾名思义,属性路由使用属性来定义路由.通过属性路由,我们可以更好地控制We ...
- ASP.NET WEB API 中的路由调试与执行过程跟踪
路由调试 RouteDebugger 是调试 ASP.NET MVC 路由的一个好的工具,在ASP.NET WEB API中相应的有 WebApiRouteDebugger ,Nuget安装 Inst ...
- 在 ASP.NET Web API 中,使用 命名空间(namespace) 来作为路由的参数
这个问题来源于我想在 Web API 中使用相同的控制器名称(Controller)在不同的命名空间下,但是 Web API 的默认 路由(Route) 机制是会忽略命名空间的不同的,如果这样做,会看 ...
- Web APi入门之Self-Host寄宿及路由原理(二)
前言 刚开始表面上感觉Web API内容似乎没什么,也就是返回JSON数据,事实上远非我所想,不去研究不知道,其中的水还是比较深,那又如何,一步一个脚印来学习都将迎刃而解. Self-Host 我们知 ...
- Web APi入门之Self-Host寄宿及路由原理
前言 刚开始表面上感觉Web API内容似乎没什么,也就是返回JSON数据,事实上远非我所想,不去研究不知道,其中的水还是比较深,那又如何,一步一个脚印来学习都将迎刃而解. Self-Host 我们知 ...
- Web APi入门之Self-Host寄宿及路由原理 【转载】
前言 刚开始表面上感觉Web API内容似乎没什么,也就是返回JSON数据,事实上远非我所想,不去研究不知道,其中的水还是比较深,那又如何,一步一个脚印来学习都将迎刃而解. Self-Host 我们知 ...
- Entity Framework 6 Recipes 2nd Edition(9-3)译->找出Web API中发生了什么变化
9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Fri ...
随机推荐
- Server socket
用法都一样 区别: self.request TCP self.requsst 代表具体的链接 UDP self.requst 代表一个小元组(元组里面: 第一个元素 客户端发来的数据 ,第 ...
- BZOJ 4196 软件包管理器
树链剖分 建树之后,安装软件就是让跟节点到安装的节点路径所有点权+1,卸载软件就是让一个节点和他的子数-1 要求变化数量的话直接求和相减就行啦(绝对值) 注意一点,一开始的lazyatag应该是-1, ...
- DevOps 10秒钟进阶大师之路
简介:DevOps(Development开发和Operations运维的组合词),是一种文化.原则.思维.理念.组织. DevOps 是一个完整的面向开发.运维的工作流,以 IT 自动化以及持续集成 ...
- jupyter更改存储路径
实习了两个月爬虫,第一个月学到了不少东西,尤其是真实链接的抓取还有定时爬虫以及一些常规的反爬策略. 但是感觉第二个月的工作内容和预想的轨道渐渐脱离,所以选择了辞职,停下来重新看一下以后的路该怎么走,调 ...
- MT【286】最佳有理逼近
2017北大优秀中学生夏令营已知$\omega $是整系数方程$x^2+ax+b=0$的一个无理数根, 求证:存在常数$C$,使得对任意互质的正整数$p,q$都有$$|\omega-\dfrac{p} ...
- Android工程图片资源命名禁忌
Android工程中,res\drawable\ 文件夹下所有的图片资源文件命名,不允许: 1. 大写字母 从Eclipse的这个报错可以知道资源文件的命名规则. Invalid file name: ...
- Atlantis HDU - 1542 (扫描线,线段树)
扫描线的模板题,先把信息接收,然后排序,记录下上边和下边,然后用一条虚拟的线从下往上扫.如果我扫到的是下边,那么久用线段树在这个区间内加上1,表示这个区间现在是有的,等我扫描到上边的时候在加上-1,把 ...
- [luogu3369][普通平衡树]
题目链接 思路 模板 只是有几个容易出错的地方 第45行容易忘记 第54行里面的cnt--和siz--容易忘记 第56行是根据id判断不是val 第60行siz--容易忘记 第64行是siz+1不是s ...
- 团体程序设计天梯赛(CCCC) L3014 周游世界 BFS证明
团体程序设计天梯赛代码.体现代码技巧,比赛技巧. https://github.com/congmingyige/cccc_code
- io系列之字符流
java中io流系统庞大,知识点众多,作为小白通过五天的视频书籍学习后,总结了io系列的随笔,以便将来复习查看. 本篇为此系列随笔的第一篇:io系列之字符流. IO流 :对数据的传输流向进行操作,ja ...