[译]ASP.NET Core 2.0 路由引擎
问题
ASP.NET Core 2.0的路由引擎是如何工作的?
答案
创建一个空项目,为Startup类添加MVC服务和请求中间件:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
} public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseMvc(routes =>
{
routes.MapRoute(
name: "goto_one",
template: "one",
defaults: new { controller = "Home", action = "PageOne" }); routes.MapRoute(
name: "goto_two",
template: "two/{id?}",
defaults: new { controller = "Home", action = "PageTwo" }); routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
创建一个控制器HomeController,来演示常规路由:
public class HomeController : Controller
{
public IActionResult Index()
{
return Content("Home/Index");
} public IActionResult PageOne()
{
return Content("Home/One");
} [HttpGet]
public IActionResult PageTwo()
{
return Content("(GET) Home/Two");
} [HttpPost]
public IActionResult PageTwo(int id)
{
return Content($"(POST) Home/Two: {id}");
}
}
创建一个控制器WorkController,来演示特性路由:
[Route("work")]
public class WorkController : Controller
{
public IActionResult Index()
{
return Content("Work/Index");
} [Route("one")]
public IActionResult PageOne()
{
return Content("Work/One");
} [HttpGet("two")]
public IActionResult PageTwo()
{
return Content("(GET) Work/Two");
} [HttpPost("two/{id?}")]
public IActionResult PageTwo(int id)
{
return Content($"(POST) Work/Two: {id}");
}
}
讨论
ASP.NET Core的路由引擎可以将传入的请求映射到控制器和它们的方法中。这是通过向请求管道中添加路由中间件实现的,具体来说是使用IRouteBuilder将URL规则(模板)映射到一个控制器的方法。
路由模板
路由模板可以使用字面值和标记(标识路由参数)。在匹配一个路由时,字面值会严格匹配URL中的文本,而标记会被替换掉。
为了匹配一个模板,模板中必须包含控制器和方法标记以便定位控制器方法(这是MVC的核心信息)。模板中的其它标记被映射为方法的参数(通过模型绑定实现)。
当添加一个路由映射时,可以为标记提供缺省值。当模板中不包含控制器和方法标记时会很有用。模板也可以包含对应于方法参数的可选标记。
让我们来看一个示例模板:
contact/{controller=Home}/{action=Index}/{id?}
注意如下几点:
- 标记包含中大括号中。这里有三个标记,分别是controller,action和id。
- 模板中包含一个字面值contact,它会匹配URL中的文本。
- 已经为controller(Home)和action(Index)提供了默认值。
- 可选标记通过问号来声明。
下面的URL会匹配这个模板:
- /contact/Home/Index/1: 所有标记都有值。
- /contact/Home/Index: 忽略了可选标记。
- /contact/Home: 忽略了action标记,将使用默认值Index。
- /contact: 忽略了controller和action标记,将分别使用其默认值Home和Index。
常规路由
常规路由为URL路径建立一个约定, 例如给定一个模板:
- 第一个标记映射到控制器
- 第二个标记映射到方法
- 第三个标记映射到可选的方法参数id
你也可以从模板中省略控制器和方法,只要你为它们提供缺省值就行了。比如下面的路由会映射到地址/one,因为通过defaults提供了所需的控制器和方法标记:
routes.MapRoute(
name: "goto_one",
template: "one",
defaults: new { controller = "Home", action = "PageOne" });
注:请将此特定路由添加到通用路由之前,因为路由是按照定义的顺序执行的,一旦某个路由匹配成功,则整个匹配流程就会终结。
由于路由中间件只使用了控制器和方法标记来映射到一个控制器方法,因此同一个控制器中放置多个同名的的方法将会抛出异常。为了解决这个问题,可以使用方法上的IActionConstraint特性(比如HttpGet,HttpPost等特性):
[HttpGet("two")]
public IActionResult PageTwo()
{
return Content("(GET) Work/Two");
} [HttpPost("two/{id?}")]
public IActionResult PageTwo(int id)
{
return Content($"(POST) Work/Two: {id}");
}
====start by sanshi=========================
为了观察控制器中同名方法出现的异常,我们首先需要修改Configure()方法,添加开发时异常处理中间件:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} app.UseMvc(routes => ....);
}
修改HomeController:
public IActionResult PageTwo()
{
return Content("(GET) Home/Two");
}
public IActionResult PageTwo(int id)
{
return Content($"(POST) Home/Two: {id}");
}
看似很正常的重载函数,但是放到控制器中会抛出异常。
在浏览器地址栏敲入:http://localhost:65415/Home/PageTwo,观看到异常页面:
====end by sanshi=========================
特性路由
特性路由通过直接为控制器和方法提供路由模板来实现。
我们可以使用[Route]或者[HttpGet](或者其他动词)特性来指定模板。这些模板可以包含字面值和标记(不能包含控制器和方法标记)。
运行时,控制器的特性模板和方法的特性模板会被合并到一起,比如,在WorkController中,PageOne方法可以通过/work/one访问:
[Route("work")]
public class WorkController : Controller
{
[Route("one")]
public IActionResult PageOne()
{
return Content("Work/One");
}
}
源代码下载
原文:https://tahirnaushad.com/2017/08/20/asp-net-core-mvc-routing/
[译]ASP.NET Core 2.0 路由引擎的更多相关文章
- [译]ASP.NET Core 2.0 路由引擎之网址生成
问题 如何在ASP.NET Core 2.0中由路由引擎来生成网址? 答案 新建一个空项目,修改Startup.cs文件,添加MVC服务和中间件: public void ConfigureServi ...
- [译]ASP.NET Core 2.0 视图引擎
问题 如何在ASP.NET Core 2.0中使用Razor引擎来创建视图? 答案 新建一个空项目,修改Startup.cs,添加MVC服务和请求中间件: public void ConfigureS ...
- [译]ASP.NET Core 2.0 系列文章目录
基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...
- [译]ASP.NET Core 2.0 部分视图
问题 如何在ASP.NET Core 2.0中使用部分视图来重用页面的公共部分? 答案 新建一个空项目,在Startup中添加MVC服务和中间件: public void ConfigureServi ...
- [译]ASP.NET Core 2.0 区域
问题 如何将一个规模庞大的ASP.NET Core 2.0应用程序进行逻辑分组? 答案 新建一个ASP.NET Core 2.0空项目,修改Startup类,增加Mvc服务和中间件: public v ...
- [译]ASP.NET Core 2.0 中间件
问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...
- [译]ASP.NET Core 2.0 带初始参数的中间件
问题 如何在ASP.NET Core 2.0向中间件传入初始参数? 答案 在一个空项目中,创建一个POCO(Plain Old CLR Object)来保存中间件所需的参数: public class ...
- [译]ASP.NET Core 2.0 全局配置项
问题 如何在 ASP.NET Core 2.0 应用程序中读取全局配置项? 答案 首先新建一个空项目,并添加两个配置文件: 1. appsettings.json { "Section1&q ...
- [译]ASP.NET Core 2.0 机密配置项
问题 如何在ASP.NET Core 2.0中保存机密配置项(不用将其暴露给源代码管理器)? 答案 创建一个ASP.NET Core 2.0空项目,在项目节点上点击右键,并点击菜单项 - 管理用户机密 ...
随机推荐
- 警惕Java编译器中那些“蜜糖”陷阱
一.前言 随着Java编译器不断地向前发展,它为程序员们提供了越来越多的“蜜糖”(compiler suger),极大地方便了程序的开发,例如,foreach的增强模式,自动拆箱与装箱以及字符串的连接 ...
- String类的一些转换功能(6)
1:把字符串转换成字节数组 getBytes() 如: String s = "你好啊!" //编码 byte [] arr = s.getBytes();//这里默认编码格式是g ...
- 接口interface,接口继承implements
php中,只支持从一个类继承,不支持从两个或者更多的类同时继承.从两个或者两个以上的类继承的能力被称为多重继承.php在设计上是禁止这种功能的.原因在于,避免多个类带来的复杂性.当发现需要从两个或者更 ...
- Bit Byte WORD DWORD的区别和联系
typedef unsigned short WORD; 16位短整数,可以表示0-65535之间的整数 而char是8位. int和机器类型有关.如16位机,就表示16位.32位机就表示32位 基本 ...
- http://codeforces.com/contest/536/problem/B
B. Tavas and Malekas time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- Ubuntu 16安装GPU版本tensorflow
pre { direction: ltr; color: rgb(0, 0, 0) } pre.western { font-family: "Liberation Mono", ...
- 嵌入式linux开发之工具------tftp
我在嵌入式linux开发中用到tftp的地方主要有2个方面: 1.是在嵌入式目标板启动时,bootloader启动时通过uEnv文件,下载dtb文件和kernel文件: 2.是在嵌入式目标板启动后,通 ...
- mysql中将时间转为秒
项目中遇到的问题,需要将时间(时 分 秒)转为秒,业务上处理有些麻烦,尝试找了多种处理函数,然而并没有用 完美解决办法: TIME_TO_SEC 格式'HH:MM:SS'或HHMMSS SELEC ...
- hiveQL去重
去重: 以id进行分组,然后取出每组的第一个 ; 以id进行分组,按照create_time降序排序后,然后取出每组的第一个 ; 将去重后的数据重新存储 ; 去重之后与其他表join算匹配数 sele ...
- 【Spring】浅谈spring推荐构造器注入
一.前言 Spring框架对Java开发的重要性不言而喻,其核心特性就是IOC(Inversion of Control, 控制反转)和AOP,平时使用最多的就是其中的IOC,我们通过将组件交由S ...