Routing in ASP.NET Core
.NET-Core Series
- Server in ASP.NET-Core
- DI in ASP.NET-Core
- Routing in ASP.NET-Core
- Error Handling in ASP.NET-Core
- WebSocket in ASP.NET-Core(一)
- WebSocket in ASP.NET-Core(二)
- To be Continue...
2017年 9月9日更新
路由属性中还可以结合 正则表达式 和其他属性来限制参数
可以参考
- http://sampathloku.blogspot.com/2013/12/attribute-routing-with-aspnet-mvc-5.html
- https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/routing#route-template-reference
[Route("multi/{id:int}")]
public string IntParamsFun()
{
return "Hello,success invoke!";
}
http://localhost:52298/multi/11.2 ` 404 not found`
http://localhost:52298/multi/11 `200 ok `
下面是正则表达式的例子
[Route("regex/{id:regex(^\\d+)}")]
public string RegexFunc()
{
return "Hello,Robert, Regex Invoke Success!";
}
疑问1 当我需要匹配两个参数的路由时需要怎么做,
rewrite-rule/(\d+)/(\d+) 比如这样,就像 rewrite-rule/1111/1111 ,这个的意思相当于 action 是数字的,id 也是数字的 ,可以实现吗? 好像不行。
在startup 中配置
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Regex",
template: "MultiRegex/{param1}/{param2}",
defaults: new { controller = "Rewrite", action = "MultiRegexFunc" },
constraints: new { param1 = @"^\d+", param2 = @"\d+" });
routes.MapRoute(
name: "default",
template: "{Controller}/{Action}/{Id?}",
defaults: new { controller = "Home", action = "Index" });
});
前言
这篇文章是关于 ASP.NET Core(下文中用AEC简写表示 ASP.NET Core) 中的路由的。主要是从下面两个AEC 官方文档上了解到的内容,再结合自己实践中得出的一些结论,以及一些建议和注意事项。
路由是什么
首先讲讲AEC Mvc中的路由,AEC 中使用 Routing Middleware 即路由中间件来处理URL中的请求,然后映射到相应的Action中。官网的这张Middleware图感觉挺不错。表示了路由的请求以及相应的逻辑。More about Middleware
路由一般定义在Startup.cs 中,或者直接以 Attribute 形式定义在 Controller 中,这两种方法可以混合起来使用,因为两种各有偏好,比如在设计WebApi的时候,可能用属性来定义路由会比较多。向下面这样:
[Route("Hello")]
[HttpGet()]
public IActionResult Index(){
//return View or something.
}
如何使用,创建你的路由
接下来就讲讲如何创建路由,一般我们都是在 Starup.cs 的 Configure 的 app.UseMvc 中定义创建的。就像下面这样,
//Startup.cs
app.UseMvc(options =>
{
options.MapRoute("default","{Controller=Home}/{Action=Index}/{Id?}")
});
//HomeController.cs
public Class HomeControler
{
public string Index(int? id)
{
return $"Hello,Robert!+{id}";
}
}
这样我们就创建好了一个路由,上面的匹配的URL就像这样 /Home/Index/1或者 Home/Index 或者 /Home。因为是默认路由,所以我们比如网页上直接输入localhost:5000的话,就直接导航到这个地方了。
如下图所示:

如果感觉上面的那个写法有点复杂,而且你的项目又只有一个路由的话,你可以直接这样
app.UseMvcWithDefaultRoute();
//Equals to below
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
});
说路由是用 Middleware 的,那么怎么用起了 UseMvc 呢,当我们在使用UseMvc时,就相当于下面这样
var routes = new RouteBuilder(app);
routes.DefaultHandle = new MvcRouteHandler(..);
routes.MapRoute(...);
//创建路由集合,并添加中间件
app.UseRouter(routes.Build());
如果你有多个路由,那么直接在 app.UseMvc 中再自己定义就可以了
app.UseMvc(routes =>
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
routes.MapRoute("First","..")
//...
});
如果有下面一段代码:
public class TestController
{
public string Test(int id)
{
return "Test1";
}
public string Test(int id ,string s)
{
return "Test2";
}
}
当我使用URL 为/Test/Test/11/ 你觉得结果会是什么? 结果就是这个
Microsoft.AspNetCore.Mvc.Internal.AmbiguousActionException: Multiple actions matched. The following actions matched route data and had all constraints satisfied:
程序判断不出哪个到底是最符合的,难道就不能有同名的ActionName 吗? 未必。接下来就要介绍另外一种 Attribute 形式的路由。
回到上面,我如果改成下面这样,那么就可以完美运行了,
public class TestController
{
public string Test(int id)
{
return "Test1";
}
[HttpPost]
public string Test(int id ,string s)
{
return "Test2";
}
}
结果就是下图预想的这样

除了上面的方式,我们可以直接改写我们刚刚在使用 app.UseMvc() 的那种方式,改为用属性,如下所示:
public class HomeController
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public string Index(int? id){
return "Hello, Robert!"
}
}
我们可以使用同样名字的URL,但是导航到不同的地址,这可以通过Http Attribute来实现,如下图所示:
[HttpGet("/products")]
public IActionResult ListProducts()
{
//...
}
[HttpPost("/products")]
public IActionResult CreateProduct(...)
{
//...
}
还有一种情况就是在我们开发Api 的时候挺有用的,比如我想给我的路径前面都加上/api/
那么你可以直接在Class 上面定义属性
[Route("api")]
public class MyApiController
{
//...
}
当然,你也可以定义自己的属性路由,比如像下面这样,
public class MyTestControllerAttribute : Attribute,IRouteTemplateProvider
{
public string Template => "test/[controller]";
public int? Order {get;set;}
public string Name{get;set;}
}
当[MyTestController] 使用时,Template 则自动设置为 test/[controller]
注意事项
需要注意的是,路由是有顺序的,这个顺序就是按照你定义时的顺序,当发起一个请求时,逐个遍历,找到后导航到对应的action,找不到则返回404。
参考链接
- https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing
- https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing
- 建议多阅读官方英文原版文档,毕竟每个人的理解都是不一样的。
Routing in ASP.NET Core的更多相关文章
- 初识ASP.NET CORE:一、HTTP pipeline
完整的http请求在asp.net framework中的处理流程: Asp.Net HttpRequest--> HTTP.exe--> inetinfo.exe(w3wp.exe)-& ...
- ASP.NET Core 2 学习笔记(七)路由
ASP.NET Core通过路由(Routing)设定,将定义的URL规则找到相对应行为:当使用者Request的URL满足特定规则条件时,则自动对应到相符合的行为处理.从ASP.NET就已经存在的架 ...
- ASP.NET Core 2 学习笔记(十二)REST-Like API
Restful几乎已算是API设计的标准,通过HTTP Method区分新增(Create).查询(Read).修改(Update)和删除(Delete),简称CRUD四种数据存取方式,简约又直接的风 ...
- ASP.NET Core 3.0中使用动态控制器路由
原文:Dynamic controller routing in ASP.NET Core 3.0 作者:Filip W 译文:https://www.cnblogs.com/lwqlun/p/114 ...
- 【翻译】asp.net core 3.0基本概念
这篇文章描述了开发asp.net core所需要掌握的基本概念. 原文地址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/?vie ...
- Advanced Architecture for ASP.NET Core Web API
转自: https://www.infoq.com/articles/advanced-architecture-aspnet-core ASP.NET Core's new architecture ...
- ASP.NET CORE 基础知识(一):概述【下】
此为系列文章,对MSDN ASP.NET Core 的官方文档进行系统学习与翻译.其中或许会添加本人对 ASP.NET Core 的浅显理解 配置 ASP.NET Core提供了一个配置框架,其能够从 ...
- ASP.NET Core 源码阅读笔记(5) ---Microsoft.AspNetCore.Routing路由
这篇随笔讲讲路由功能,主要内容在项目Microsoft.AspNetCore.Routing中,可以在GitHub上找到,Routing项目地址. 路由功能是大家都很熟悉的功能,使用起来也十分简单,从 ...
- ASP.NET Core MVC 源码学习:Routing 路由
前言 最近打算抽时间看一下 ASP.NET Core MVC 的源码,特此把自己学习到的内容记录下来,也算是做个笔记吧. 路由作为 MVC 的基本部分,所以在学习 MVC 的其他源码之前还是先学习一下 ...
随机推荐
- BOOT BIOS UEFI
1. 什么是BOOT? BOOT其实是你按开机键之后,在电脑微软操作系统运行之前就自动运行的一段小程序.表象上就是windows引导画面之前那些黑屏蓝屏的英文那个阶段就是BOOT了.通过这段小程序,它 ...
- SQLite在C#中的安装与操作
SQLite 介绍 SQLite,是一款轻型的数据库,用于本地的数据储存. 先说说优点,它占用资源非常的低,在嵌入式设备中需要几百K的内存就够了:作为轻量级数据库,他的处理速度也足够快:支持的的容量级 ...
- Win7怎样禁用自带IE浏览器
Win7怎样禁用自带IE浏览器 ------------ 1.单击开始按钮,从弹出的菜单中,选择控制面板. 2.在控制面板界面,单击程序和功能 3.在程序界面中单击选择“打开或关闭Windows功能” ...
- CY7C68013A控制传输
大家好,你们的大熊又回来了.本篇文章我们来重点了解一下USB设备的四大传输方式之一--控制传输.不同于其他三种传输方式,控制传输有其独特的作用和功能,是一个USB设备必须支持的传输方式.控制传输对带宽 ...
- JS中的循环结构
[循环结构的执行步骤]1.声明循环变量:2.判断循环条件3.执行循环体操作4.更新循环变量然后循环执行2-4,直到条件不成立时,跳出循环.while循环()中的表达式,运算结果可以是各种类型,但是最终 ...
- 【Vue】Vue中的父子组件通讯以及使用sync同步父子组件数据
前言: 之前写过一篇文章<在不同场景下Vue组件间的数据交流>,但现在来看,其中关于“父子组件通信”的介绍仍有诸多缺漏或者不当之处, 正好这几天学习了关于用sync修饰符做父子组件数据双向 ...
- 【Linux相识相知】yum的配置使用和程序包的编译安装
在上一篇博客中,写到了如何使用rpm命令来安装.卸载软件等,但是大家都知道,各个软件包之间可能存在依赖关系,如果安装某个软件需要额外的依赖其他若干的包,那么我们就需要将其他额外的包一个一个的安装上去, ...
- chrome保持元素hover,active状态
审查元素,选中需要hover的标签 点击"Styles"菜单中的":hov",弹出 Force element state 选中相应的 :hover :acti ...
- [Vue安装教程]十分钟学会vue 安装
Vue的安装主要有一下几个步骤: 1.安装npm淘宝镜像 npm install -g cnpm --registry=https://registry.npm.taobao.org 2.安装脚手架工 ...
- vue中组件的四种方法总结
希望对大家有用 全局组件的第一种写法 html: <div id = "app"> <show></show></div> js: ...