昨们可以利用路由为应用步伐创建URL模板,这些路由模板匹配进入的哀求而且分发这些哀求到应用步伐的闭幕点,闭幕点负责处置惩罚这些哀求,在ASP.NET Core MVC中大多数的闭幕点是Controllers
1 匹配进入的URL到Controllers和Actions在ASP.NET Core 中支持两种范例的路由:
1 基于左券路由 – 在Program.cs 类中利用
2 基于Attribute的路由 – 路由作为C# 特性利用在Controllers和action方法上
昨们通过一个例子来相识ASP.NET Core 路由是怎样工作
1 ASP.NET Core MVC 路由例子
在Visual Studio 创建一个新的ASP.NET Core MVC项目,名字为URLRouting

创建之后,在办理方案中打开Program.cs文件,将表现应用步伐默认的路由:
app.UseRouting();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
昨们设置app.UseRouting() 路由中心件,接着为应用步伐添加一个default路由app.MapControllerRoute()方法,这个路由根据url指定的模板映射到闭幕点,这意味着当应用步伐吸收url匹配 {controller=Home}/{action=Index}/{id?} 会调用Home控制器中的Index方法
留意: {controller=Home}意味着假如没有指定控制器,将利用HomeController作为默认控制器,雷同的{action=Index} 意味着假如action没有被详细指定,将会调用Index作为默认的action,{id?} - id 参数是可选的,在该参数背面利用"?"
这个路由模板匹配如下URL:
ASP.NET Core 应用步伐中有一个HomeController.cs,该控制器内里包罗一个Index方法,代码如下:using AspNetCore.URLRouting.Models;
using Microsoft.AspNetCore.Mvc;
using System.Diagnostics;
namespace AspNetCore.URLRouting.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
return View();
}
public IActionResult Privacy()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}
如今,修改Index.cshtml 视图代码(Views->Home)文件夹内:
@{
Layout = ;
}
@{
ViewData["Title"] = "Routing";
}
<h1>'Home' Controller, 'Index' View</h1>
运行应步伐,你将看到Index视图表现到欣赏器,图片如下:

https://localhost:7134 昨们没有指定Controller或Action,但是在路由中界说了一个默认的Controller和Actioin分别是"HomeController"和"Index",因此哀求能映射到HomeController的Action 方法,昨们可以利用下面地点到达雷同结果,访问 –
https://localhost:7134/Home/Index
在表明ASP.NET Core 路由怎样工作之前,起首表明一下URL中的路由段
段是URL的一部门,除了HostName和查询字符串,利用"/"字符举行分割,下面图片表明:
因此,URL可以有多个段,但是大多数应用步伐必要的段不会大于3个
当HTTP 哀求进入应用步伐时,ASP.NET Core 路由匹配 URL 并从中提取每个段的值,在Program.cs类中,昨们能看到默认左券路由最多能匹配3个段
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
2.1 .NET Core 5.0 和 ASP.NET Core 3.0
假如你利用的这个版本,查抄Startup类中的Configure()方法,会添加一个默认路由("default"是一个名字,你可以利用别的名字),利用了UseEndpoints 方法,昨们利用MapControllerRoute()方法来创建路由,代码如下:app.UseEndpoints(endpoints =>
{
// Default route
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
留意:假如没有指定URL段,会利用默认路由模板中提供的值
当运行应用步伐时,你会发现Home控制器中的Index视图被调用,只管在URL中没有包罗段(https://localhost:7134/),这是利用了路由模板中的默认值( Home和Index)
昨们可以看到当前路由在URL中匹配3个段,假如大于3个段将失败并给404错误消息
如今移除默认的Controller和Action 段,而且从路由移除id段:app.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}");
运行应用步伐,你将获取404错误,由于路由体系不能映射到任何Controller的URL,如下图所示:
打开https://localhost:7134/Home/Index 并添加Controller和Action的名字,这次你将看到Home控制器中的Index方法被调用因此这个路由将匹配2个段在URL,别的数目的段,像 0,1,3,4....它将失败并给予404错误消息
下面的表给予了全部大概匹配的URL:
段
| URL
| 映射到
|
0
| /
| 无法匹配 |
1 | /Home
| 无法匹配
|
2 | /Home/Index
| controller=Home action=Index
|
2
| /Home/Show/4
| 无法匹配
|
3
| /Home/Show/4
| 无法匹配
|
3 ASP.NET Core 静态路由
ASP.NET Core 支持静态路由,为了明白它,移除默认路由并添加一个路由静态文本:
app.MapControllerRoute(
name: "news1",
pattern: "News/{controller=Home}/{action=Index}");
路由包罗一个静态文本-News,运行应用步伐并在欣赏器中打开如下地点
https://localhost:7134/News,你会发现Home控制器的Index方法被调用
让昨们明白发生了什么,路由匹配3个段,第一个是News一个静态文本,第二个和第三个段Controller和Action是可选的,假如省略,默认会访问Home控制器的Index方法
你也可以在静态文本中联合变量段(像Controller大概action),利用下面路由模板:app.MapControllerRoute(
name: "news2",
pattern: "News{controller}/{action}");
这里昨们添加了静态文本News联合Controller段的值,如今运行应用步伐而且进入https://localhost:7134/NewsHome/Index,你会发现Home控制器中的Index方法被调用
3.1 保存旧的路由
通过利用静态路由昨们能保存旧的URL,假设昨们有一个Shopping的Controller,如今你可以利用HomeController更换Shopping(即/Shopping/Clothes, /Shopping/Electronics, /Shopping/Grocery等)
你在Program类中添加这个路由:
app.MapControllerRoute(
name: "shop",
pattern: "Shopping/{action}",
defaults: new { controller = "Home" });
路由匹配两个段,第一个段是Shopping,第二个段是action方法,URL模板没有包罗Controller段,因此这时会利用默认值,默认参数提供了一个HomeController的值/Shopping/Clothes, /Shopping/Electronics, /Shopping/Grocery 会用HomeController更换ShoppingController
打开URL-https://localhost:7134/Shopping/Index 在欣赏器,你将发现HomeController中的Index方法被调用, 如下图所示:
3.2 Controller和Action 在路由中的默认值
假如您只想要一个特定的控制器和Action应该映射到一个URL,那么您必须提供Controller和Action的默认值,如下面的路由所示:
app.MapControllerRoute(
name: "old",
pattern: "Shopping/Old",
defaults: new { controller = "Home", action = "Index" });
https://localhost:7134/Shopping/Old 会映射到Home中的 Index方法,如下图所示:
3.3 ASP.NET Core 多个路由
路由按照在Program类中界说的次序利用,ASP.NET Core 路由实验将传入的 URL 与第一个界说的路由举行匹配,在没有匹配乐成时才继承到下一个路由, 因此,你必须界说最优的门路
让昨们添加下面2个路由在Program.cs 类中:
app.MapControllerRoute(
name: "old",
pattern: "Shopping/Old",
defaults: new { controller = "Home", action = "Index" });
app.MapControllerRoute(
name: "shop",
pattern: "Shopping/{action}",
defaults: new { controller = "Home" });
在HomeController中添加一个新的Action方法Old, 代码如下: public IActionResult Old()
{
return View();
}
下一步,在Views->Home文件夹添加Old视图,内容如下:@{
Layout = ;
}
<h1>'Home' Controller, 'Old' View</h1>
运行应用步伐并打开https://localhost:7134/Shopping/Old 在欣赏器中,这次你将发现HomeController中的Index方法被调用,看如下图片:

当昨们哀求https://localhost:7134/Shopping/Old地点时,路由体系开始从第一个路由匹配url,第一个路由被乐成匹配,以是Home控制器中的Index方法被调用如今,昨们更改一下路由的次序,将第二个路由放到第一个路由之前:
app.MapControllerRoute(
name: "shop",
pattern: "Shopping/{action}",
defaults: new { controller = "Home" });
app.MapControllerRoute(
name: "old",
pattern: "Shopping/Old",
defaults: new { controller = "Home", action = "Index" });
昨们再次哀求https://localhost:7134/Shopping/Old地点时,这次你会发现Home控制器中的Old方法被调用,如下图所示:
在Program类中改变了路由次序之后,路由体系针对URL发现了差别的匹配,昨们记着将更详细的路由放在第一位,否则,路由体系将做错误的映射
到现在为止,昨们已经在路由中看到controller和action段变量,你可以在路由中添加你本身的变量段,让昨们看一下详细怎样做移除全部的路由,在ASP.NET Core应用步伐的Program.cs中添加下面代码:
app.MapControllerRoute(
name: "MyRoute",
pattern: "{controller=Home}/{action=Index}/{id}");
在这个路由中我添加了自界说的段叫id,接下来在HomeController中添加一个新的Action叫Check:
public IActionResult Check()
{
ViewBag.ValueofId = RouteData.Values["id"];
return View();
}
这个action方法利用RouteData.Values属性获取路由模板中客户自界说变量id的值,而且将值存储在ViewBag变量
创建一个check 视图在Home->Check文件夹下,Check视图的代码如下
@{
Layout = ;
}
<h1>'Home' Controller, 'Check' View</h1>
<h2>Id value is: @ViewBag.ValueofId</h2>
运行步伐进入
https://localhost:7134/Home/Check/cSharp
ASP.NET Core 路由体系将匹配第三段的值在URL,作为id变量的值,你将看到id值是cSharp被表现到欣赏器上:

假如你哀求
https://localhost:7134/Home/Check,URL中第三段没有值,路由体系没有发现与之匹配的路由,因此在欣赏器中会表现404错误
5 在Action方法的参数中获取路由变量
假如昨们在Action方法中添加一个参数利用和URL雷同名字,dotnet将获取url变量中的值通报到action方法参数
app.MapControllerRoute(
name: "MyRoute",
pattern: "{controller=Home}/{action=Index}/{id}");
为了能获取url中id的值,昨们在action方法中添加一个id参数,因此昨们在action方法中添加一个id的参数:public IActionResult Check(int id)
{
ViewBag.ValueofId = id;
return View();
}
昨们留意到在方法内部,昨们仅仅将id变量的值赋值给ViewBag变,访问
https://localhost:7134/Home/Check/100
你会看到100表现在视图上:

留意:昨们将id参数声明为为Int范例,dotnet会实验将URL中100转换到action方法的参数所声明的范例,这里利用了模子绑定相干技能技能
雷同,昨们将action方法中参数范例修改为string大概DateTime,dotnet将主动转换id的值到指定的范例
比方:昨们把check方法参数的范例从int改为string
public IActionResult Check(string id)
{
ViewBag.ValueofId = id;
return View();
}
当哀求URL-https://localhost:7134/Home/Check/hello 大概https://localhost:7134/Home/Check/100,框架会主动将客户自界说id变量的值(hello 和100)转化成string6 ASP.NET Core 路由可选参数
假如路由段是可选范例的参数,在调用过程中你不必要指定该参数,通过利用问号(?)来指定可选参数在你的应用步伐移除全部的路由,添加下面代码,昨们利用?将id段标志为可选参数app.MapControllerRoute(
name: "MyRoute1",
pattern: "{controller=Home}/{action=Index}/{id?}");
当你没有给可选的参数提供值时,路由也会被匹配乐成,只不外id值会被设置成
昨们在HomeController的check方法测试一下:public IActionResult Check()
{
ViewBag.ValueofId = RouteData.Values["id"];
return View();
}
运行步伐,访问URL-https://localhost:7134/Home/Check
这是由于路由没有在可选的参数中发现id的值,因此空值会表现在欣赏器
接下来,在HomeController中修改Check方法:
public IActionResult Check(string id)
{
ViewBag.ValueofId = id ?? " Value";
return View();
}
将参数id范例修改为string范例,如今代码ViewBag.ValueofId = id ?? " Value" 表现假如id的值为,会将 Value的值赋值给ViewBag变量,否则,将id的值赋值给ViewBag变量
运行步伐而且访问-https://localhost:7134/Home/Check 地点,你会发现 Value表现在欣赏器:
到现在为止,昨们利用的路由的URL最多只有3个段与之匹配,假如你的URL停止的数目大于3个,昨们应该怎么办呢?
一种方法针对大于3个段添加新的路由,比方:匹配4个段URL-https://localhost:7134/Home/Check/Hello/World
这时你可以添加一个新的路由
app.MapControllerRoute(
name: "MyRoute2",
pattern: "{controller=Home}/{action=Index}/{id?}/{idtwo?}");
假如第5个段出现,你不得不添加别的一个新的路由来匹配5段这很乏味而且会有大量代码重复,可以在路由中利用*catchall ,在url段的变量中它将饰演通配符的脚色
昨们将路由的第四段修改为 {*catchall} , 它将是:
app.MapControllerRoute(
name: "MyRoute2",
pattern: "{controller=Home}/{action=Index}/{id?}/{*catchall}");
昨们已经添加了{*catchall}作为在路由中作为第四段,前3段分别映射到controller, action & id 变量
假如URL包罗的段大于3,catchall变量将捕捉全部的段,即:从第4段直到末了
下面表格中表现了,catchall匹配的路由
段
| URL
| 映射
|
0
| / | |
1 | /Home | |
2 | /Home/CatchallTest | |
3 | /Home/CatchallTest/Hello | |
4
| /Home/CatchallTest/Hello/ | |
5
| /Home/CatchallTest/Hello/How/Are | |
6
| /Home/CatchallTest/Hello/How/Are/U | |
为了测试,在HomeController代码中添加新的Action方法,名字为CatchallTest,代码如下:public IActionResult CatchallTest(string id, string catchall)
{
ViewBag.ValueofId = id;
ViewBag.ValueofCatchall = catchall;
return View();
}
昨们在action方法中添加了一个新的参数名字为cacthall,这个参数的值是URL中除了前3段剩余全部段的值,昨们将cacthall的值存储到ViewBag的ValueofCatchall变量中接下来添加CatchallTest视图在View->Home文件夹利用下面代码:
@{ Layout = ; }
<h1>'Home' Controller, 'CatchallTest' View</h1>
<h2>Id value is: @ViewBag.ValueofId</h2>
<h2>Catchall value is: @ViewBag.ValueofCatchall</h2>
视图将会表现ViewBag中变量的值,运行步伐且进入
URL-https://localhost:7134/Home/CatchallTest/Hello/How/Are/U你会发现catchall的值为How/Are/U表现在视图中

总结
这节昨们重要解说在Program.cs类中怎样创建路由源代码地点
https://github.com/bingbing-gui/Asp.Net-Core-Skill/tree/master/Fundamentals/AspNetCore.Route/AspNetCore.URLRouting参考文献
[1]
邀请