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 ...
随机推荐
- 【XSY2754】求和 莫比乌斯反演 杜教筛
题目描述 给你\(n,p\),求 \[ \sum_{i=1}^n\sum_{j=1}^i\sum_{k=1}^i\gcd(i,j,k)\mod p \] \(n\leq {10}^9\) 题解 \[ ...
- JS 实现DIV 滚动至顶部后固定
JS 实现DIV 滚动至顶部后固定 <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8" ...
- XAMPP Access forbidden! Error 403,You don't have permission to access the requested directory
xampp 无论在window 还是在 Mac 如出现以下错误的:通常的解决方式: 具体配置教程可以任意查相关资料既可,(配置子站子大致流程如:开启httpd.conf的inc...httpd-vho ...
- python学习日记(python2/3区别补充,is / id/ encode str,bytes)
python2和python3区别 print python2中,print 是语句 :用法 ---->print '***' python3中,print 是函数:用法----->pri ...
- Logger.error方法之打印错误异常的详细堆栈信息
一.问题场景 使用Logger.error方法时只能打印出异常类型,无法打印出详细的堆栈信息,使得定位问题变得困难和不方便. 二.先放出结论 Logger类下有多个不同的error方法,根据传入参数的 ...
- js-基本语法
条件语句 通过条件来控制程序的走向,就需要用到条件语句. 运算符 1.算术运算符: +(加). -(减). (乘). /(除). %(求余) 2.赋值运算符:=. +=. -=. =. /=. %= ...
- 「SCOI2015」国旗计划 解题报告
「SCOI2015」国旗计划 蛮有趣的一个题 注意到区间互不交错,那么如果我们已经钦定了一个区间,它选择的下一个区间是唯一的,就是和它有交且右端点在最右边的,这个可以单调队列预处理一下 然后往后面跳拿 ...
- [POI2012]STU-Well(二分答案+神仙操作)
给定一个非负整数序列A,每次操作可以选择一个数然后减掉1,要求进行不超过m次操作使得存在一个Ak=0且max{|Ai−Ai+1|}最小,输出这个最小lk以及最小值. Solution 最大值最小,显然 ...
- redis执行lua文件
1.编写lua文件 还lua表示循环插入1-100的键为1-100值为1-100的键值对到redis中 for i=0,100 do redis.call("set",i,i) e ...
- Weblate 2.11安装配置文档
一.系统环境: OS:CentOS 6.8 x64 Minimal HostName:Weblate IP:192.168.75.153 Python:2.7.13 pip:9.0.1 Weblate ...