2.2WebApi路由在Action上
这篇文章描述 ASP.NET Web API 如何将 HTTP 请求路由到特定的操作在控制器上。
有关路由的高级别概述,请参见ASP.NET Web API 的路由.
本文着眼于路由进程的详细信息。如果你创建一个 Web API 项目并发现一些请求不要路由你期望的方式,希望这篇文章将帮助。
路由具有三个主要阶段 ︰
- 匹配的 URI 到工艺路线模板。
- 选择一个控制器。
- 选择操作。
您可以用您自己的自定义行为替换一些零件的过程。在本文中,我描述的默认行为。最后,我注意到的地方,在那里你可以自定义的行为。
工艺路线模板
工艺路线模板看起来类似于 URI 路径,但它可以有占位符值,用花括号表示 ︰
"api/{controller}/public/{category}/{id}"
当你创建一个路由时,您可以为部分或全部的占位符提供默认值 ︰
您还可以提供约束,限制如何 URI 段可以匹配一个占位符 ︰
框架会尝试匹配模板的 URI 路径中的段。在模板中的文本必须完全匹配。占位符匹配任何价值,除非你指定的约束。框架与其他部分的 URI,如主机名或查询参数不匹配。框架将匹配 URI 路由表中选择的第一个路由。
有两个特别占位符:"{控制器}"和"{}"。
- "{}"控制器提供的控制器的名称。
- "行动 》 {}"提供的操作的名称。在 Web API 中,通常的约定是省略"的行动 {}"。
默认值
如果您提供默认值,该路由将与匹配 URI,它缺少这些段。例如 ︰
"Http://localhost/api/products"URI 匹配这条路线。"{类别}"段分配的默认值"全部"。
路由字典
如果框架找到了匹配的 URI,它会创建一个字典,包含为每个占位符的值。键是占位符名称,不包括大括号。这些值被从 URI 路径或默认值。这本词典存储在IHttpRouteData对象中。
在此路由匹配的阶段,特别"{}"控制器和"的行动 {}"占位符治疗就像其他占位符。它们只存储在字典中,其他值。
默认情况下可以有RouteParameter.Optional的特殊价值。如果占位符获取指定此值,值不是添加到路由字典。例如 ︰
对于"api/产品"的 URI 路径,路由字典将包含 ︰
- 控制器:"产品"
- 类别:"所有人"
然而,对于"api/产品/玩具/123",路由字典将包含 ︰
- 控制器:"产品"
- 类别:"玩具"
- id:"123"
默认设置也可以在路线模板中包含一个值未在任何地方出现。如果该路由匹配,该值存储在字典中。例如 ︰
如果 URI 路径是"api/根/8",这本字典将包含两个值 ︰
- 控制器:"客户"
- id:"8"
选择控制器
由IHttpControllerSelector.SelectController方法处理控制器所选内容。此方法采用HttpRequestMessage的实例,并返回HttpControllerDescriptor。由DefaultHttpControllerSelector类提供默认实现。此类使用一种简单的算法 ︰
- 在路由字典键"控制器"中查找。
- 采取此键的值和追加字符串"控制器",得到控制器的类型名称。
- 寻找与此类型名称的 Web API 控制器。
例如,如果路由字典包含键-值对"控制器"="产品",然后是控制器的类型是"ProductsController"。如果没有匹配的类型或多个匹配项,框架向客户端返回错误。
步骤 3, DefaultHttpControllerSelector使用IHttpControllerTypeResolver接口获取 Web API 控制器类型的列表。IHttpControllerTypeResolver的默认实现返回所有的公共类的 (a) 执行IHttpController,(b) 是不抽象,和 (c) 有一个名称,在"控制器"中结束。
选择动作
选择控制器后, 框架通过调用IHttpActionSelector.SelectAction方法将选择的行动。此方法采用HttpControllerContext并返回HttpActionDescriptor.
由ApiControllerActionSelector类提供默认实现。若要选择一个动作,它看起来在以下 ︰
- 请求的 HTTP 方法。
- 在工艺路线模板中,如果存在"的行动 {}"占位符。
- 在控制器上的操作的参数。
选择算法之前,我们需要了解一些控制器操作的东西。
在控制器上的方法被视为"行动"?当选择某个操作,框架只是看看公共实例方法的控制器上。此外,它排除了"特别的名字"方法 (构造函数、 事件、 运算符重载,等等),和从继承的方法ApiController类。
的 HTTP 方法。框架只选择匹配的要求,确定如下的 HTTP 方法的行为 ︰
- 您可以使用属性指定的 HTTP 方法 ︰ AcceptVerbs、 HttpDelete、公共、 HttpHead、 HttpOptions、 HttpPatch、 HttpPost或HttpPut.
- 否则,如果控制器方法的名称以"Get"、"开机自检"、"放"、"删除"、"头"、"选项"或"修补程序"开头,然后由公约行动支持的 HTTP 方法。
- 如果以上都不是,该方法支持邮政。
参数绑定。参数绑定是如何 Web API 创建参数的值。参数绑定的默认规则是这样的 ︰
- 简单类型是采取从 URI。
- 复杂类型是取自请求正文。
简单类型包括所有的.NET 框架基元类型,加上日期时间、十进制、 Guid,字符串和时间跨度。为每个操作,顶多一个参数可以读取请求正文。
它是可以重写默认绑定规则。请参见WebAPI 参数绑定引擎盖下.
与这种背景下,这里是行动选择算法。
- 在匹配的 HTTP 请求方法的控制器上创建的所有操作的列表。
- 如果路由字典有的"操作"项,删除其名称与此值不匹配的操作。
- 尝试匹配到的 URI,操作参数,如下所示 ︰
- 为每个操作,得到是一个简单的类型,其中绑定从 URI 获取参数的参数的列表。排除的可选参数。
- 从该列表中,试着找到适合每个参数的名称,或者路由字典或 URI 的查询字符串中。匹配项是区分大小写,并不依赖于参数顺序。
- 选择列表中的每个参数在 URI 匹配操作。
- 如果更多这一行动符合这些标准,挑选一个有大多数的参数匹配。
- 忽略[侵权]属性的行动。
步骤 #3 是最容易混淆的。其基本思想是一个参数可以获取其值,从 URI,从请求正文中,或从自定义绑定。对于来自 URI 的参数,我们想要确保 URI 实际上包含该路径 (通过路由字典) 中或在查询字符串中的参数的值。
例如,请考虑以下行动 ︰
Id参数绑定到的 URI。因此,这一行动只能匹配一个 URI,它包含"身份证号",在路由字典或查询字符串中的值。
可选参数是个例外,因为它们是可选的。为可选的参数,它是确定如果绑定不能从 URI 中获取价值。
复杂类型是个例外,出于不同的原因。复杂类型通过自定义绑定只能绑定到的 URI。但在这种情况下,框架不能预先知道是否该参数会绑定到特定的 URI。为了找到答案,它将需要调用绑定。选择算法的目标是从静态描述,在调用任何绑定之前选择的操作。因此,复杂类型被排除的匹配算法。
选择操作后,所有的参数绑定调用。
摘要 ︰
- 行动必须匹配请求的 HTTP 方法。
- 如果目前操作名称必须匹配路由字典中的"行动"条目。
- 为每个参数的作用,如果该参数是从 URI,然后参数名称必须找到路由字典或 URI 的查询字符串中。(可选参数和复杂类型的参数除外。)
- 尝试匹配最多的参数。最佳匹配可能是一种不带任何参数的方法。
扩展的示例
路线 ︰
routes.MapHttpRoute(
name: "ApiRoot",
routeTemplate: "api/root/{id}",
defaults: new { controller = "products", id = RouteParameter.Optional }
);
routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
控制器 ︰
public class ProductsController : ApiController
{
public IEnumerable<Product> GetAll() {}
public Product GetById(int id, double version = 1.0) {}
[HttpGet]
public void FindProductsByName(string name) {}
public void Post(Product value) {}
public void Put(int id, Product value) {}
}
HTTP 请求 ︰
GET http://localhost:34701/api/products/1?version=1.5&details=1
路由匹配
URI 与路由匹配的名为"DefaultApi"。路由字典包含以下项 ︰
- 控制器:"产品"
- id:"1"
路由字典不包含查询字符串参数、"版本"和"详细信息",但这些仍被视为在行动选择。
控制器所选内容
从路由字典中的"控制器"条目,控制器类型是ProductsController
.
选择动作
HTTP 请求是 GET 请求。支持 GET 的控制器行为是GetAll
、 GetById
和FindProductsByName
。路由字典不包含"行动"的条目,所以我们不需要匹配的操作名称。
接下来,我们尝试匹配参数名称的操作,只看得到的行动。
行动 | 匹配的参数 |
---|---|
GetAll |
没有一个 |
GetById |
""id |
FindProductsByName |
"名称" |
请注意,不是GetById
的版本参数,因为它是一个可选的参数。
GetAll
方法匹配琐细。GetById
方法也相匹配,因为路由字典包含"id"。FindProductsByName
方法不匹配。
GetById
方法赢了,因为它与一个参数,与GetAll
没有参数相匹配。用下面的参数值调用该方法 ︰
- id = 1
- 版本= 1.5
请注意,即使在选择算法不使用版本,参数的值来自 URI 的查询字符串。
扩展点
Web API 的某些部件中的路由选择进程提供了扩展点。
为任何这些接口提供自己的实现,请使用HttpConfiguration对象上的服务集合 ︰
2.2WebApi路由在Action上的更多相关文章
- 爱上MVC3~在控制器或Action上动态设定模板页(Layout)
回到目录 很多境况下,我们需要设置自己模块的layout,即它的布局页面,在MVC2中叫它模板页面,你可以在return view方法时设置它,当然,这不是一种好方法,因为我不想每个action都去设 ...
- WebApi:路由和Action选择
译自:http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection ...
- struts2,action上传文件
通过servlet实现文件上传,可以用用servlet接受到request的值的话:主要是这句话 List<?> items = upload.parseRequest(request); ...
- vue-router 获得上一级路由以及返回上一级路由的方法
if (this.$store.state.previousRouter.name) { this.$router.push({name: this.$store.state.previousRout ...
- 首页重定位到mian.action上
<body onload="top.location.href='<%=request.getContextPath()%>/main.action';">
- asp.net core的授权过滤器中获取action上的Attribute
var action = context.ActionDescriptor as ControllerActionDescriptor; var permission = action.MethodI ...
- MVC POST在ACTION上进行多个模型的数据绑定
首先声明,接下来的东西并不符合本人认同的严谨的MVC模式. 用MVC做项目的过程中,越来越多的用到不严谨的MVC编程. 比如,在"cshtml"文件中写: @Html.Raw(DB ...
- 工作总结 [ActionName("ss123")] 更改路由中Action名称 获取或设置操作的名称
- 解读ASP.NET 5 & MVC6系列(11):Routing路由
新版Routing功能介绍 在ASP.NET 5和MVC6中,Routing功能被全部重写了,虽然用法有些类似,但和之前的Routing原理完全不太一样了,该Routing框架不仅可以支持MVC和We ...
随机推荐
- 发布和运行HOLOLENS程序注意这里要勾上,不然就成普通的UWP程序了!
- JSON 字符串中的中括号和大括号区别详解
json 变量有两种可能, 可能是一个对象, (类似 类的实例), 也可能是一个数组!! 主要是要 从 ""语义" 上来分析, 到底该用 大括号还是用中括号: 如果从语义 ...
- 全国高校网安联赛Web专场~WriteUp
1.Sign 题目:Good Luck!flag{X-nuca@GoodLuck!} Flag直接写在题目上了,flag{X-nuca@GoodLuck!} 2.BaseCoding 提示:这是编码不 ...
- Metasploit爆破tcpwrapped服务
转自:http://www.mamicode.com/info-detail-1653722.html 一.利用nmap工具扫描目标主机 1.1 使用nmap命令对目标主机进行扫描. 1.2 在终端中 ...
- svg拉伸,原来凹凸可以这么玩
原文:http://www.smartjava.org/content/render-geographic-information-3d-threejs-and-d3js The last coupl ...
- 系统修改利器XueTr
Windows系统修改利器XueTr 周银辉 在Windows下如果遇到某些进程弄死结束不了,某些文件弄死删不掉,拷贝不出来 (可能是因为你没有管理员权限,可能是因为人家是病毒,可能是系统保护文件,可 ...
- jquery easyui 1.4.1 API( CHM版)
ChangeLog Bug The combogrid has different height than other combo components. fixed. datagrid: The r ...
- python 环境搭建
python下载地址: 进入https://www.python.org/download/releases/3.3.4/,下载Windows X86-64 MSI Installer (3.3.4) ...
- iOS——学习网址收集+如何提高iOS开发技能
1 一个比系统自带的终端好用的软件:http://www.iterm2.com 2 学习和遇到技术问题可以去的网站: CocoaChina http://developer.cocoachi ...
- 【jQuery】scroll 滚动到顶部
Jquery 实现页面滚动到顶端 $(document).ready(function () { // 滚动窗口来判断按钮显示或隐藏 $(window).scroll(function () { // ...