Mr.Gao

高先生小屋

  • 主页
  • C#
  • 每日转载

【asp.net core 系列】4 更高更强的路由

阅读数:0次 2023-03-08
字数统计: 7.6k字   |   阅读时长≈ 15分
  • 本文作者: Mr.Gao
  • 本文链接: https:/www.attachie.club/post/72.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!

0. 前言

在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转。那么,我们回过头来,再看看路由的一些其他用法。

1. 路由属性(Route Attribute)

按照英文的直接翻译,Routing Attribute 的意思是路由属性,但实际上 Attribute在微软的官方称呼是特性。嗯,所以个人觉得Route Attribute应该是特性路由,路由特性。

嗯,暂且甩开称呼的问题,小伙伴们知道这是一种使用Attribute标记的路由配置方案就行。我们之前了解的路由设置都是通过路由表设置的,而Route Attribute则是另外一种方案。

1.1 如何设置

这种方案主要是通过RouteAttribute类来设置的,我们先来看一下这个类是个什么样的吧:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class RouteAttribute : Attribute, IRouteTemplateProvider { public RouteAttribute(string template); public string Name { get; set; } public int Order { get; set; } public string Template { get; } }

AttributeUsage 这个特性是用来标注特性的适用范围的,其中AttributeTargets.Class | AttributeTargets.Method 表示这个特性是可以设置在类或者方法上的。AllMultiple表示是否允许设置多个,Inherited 表示被该特性标注的类其子类是否也自动继承了这个特性。

那么,我们了解了RouteAttribute的适用范围,继续看这个类,一共有三个属性:

  • Name 表示这个路由特性的名称
  • Order 表示启用顺序,值越小,越先被匹配。默认情况下是0
  • Template 路由解析模板,也就是在《【asp.net core 系列】2 控制器与路由的恩怨情仇》中介绍的路由表的格式串

介绍了这么多,我们先来试试看,先拿出来之前文章创建的MvcWeb项目,新建一个控制器:

using Microsoft.AspNetCore.Mvc; namespace MvcWeb.Controllers { public class RouteTestController: Controller { public IActionResult Index() { return View(); } } }

创建对应视图:

Views > RouteTest > Index.cshtml

在Index.cshtml中随便写点内容,然后保存。

然后,在RouteTestController 添加一个Route特性标记:

[Route("/Route")] public IActionResult Index() { return View(); }

启动项目,访问 http://localhost:5006/Route 后,如果不出意外可以看到跟下图类似的界面:

image-20200603002255361

那么我们试一试通过路由表设置的路径是否可以访问:

http://localhost:5006/RouteTest

image-20200603003824041

可以看到提示404,也就是说这个Action无法通过路由表的形式查找到了。

1.2 设置参数

我们知道所谓的Action其实也是一个方法,而我们通常请求一个网址的时候,网址中也带有一些查询参数。所以,这一节我们就介绍一下路由特性(属性路由)如何设置参数的解析吧。

1.2.1 不做任何操作

在RouteTestController里添加方法:

[Route("/route/norest")] public IActionResult NoRest(string name) { ViewBag.Name = name; return View(); }

创建对应的View:

<h1>@ViewBag.Name</h1>

启动程序,并访问:http://localhost:5006/route/norest

image-20200603011055468

添加 ?name=test 在上一个请求的后面:

image-20200603011147525

尝试变更name的值,可以发现网页中的值也发生了变化,证明我们可以获取到这个值。

1.2.2 当做请求目录的一部分

在上一小节中,没有对参数做任何操作,以查询参数的形式传递。在这一篇,我们可以把参数设置为请求的一部分,像目录那样,修改上一节示例代码为:

[Route("/route/norest/{name}/")] public IActionResult NoRest(string name) { ViewBag.Name = name; return View(); }

请求方式:

http://localhost:5006/route/norest/1232

image-20200603011838964

修改连接中的1232 内容,然后刷新页面,就能发现页面中的值也发生了变化

1.2.3 给参数一个默认值

之前的设置里我们都默认参数由请求URL获取,那么在这里我们介绍一下给参数一个值:

[Route("/route/norest/{name=demo}/")] public IActionResult NoRest(string name) { ViewBag.Name = name; return View(); }

访问连接:

http://localhost:5006/route/norest/

可以看见:

image-20200603014035541

设置为可空,也就是参数可以不传:

[Route("/route/norest/{name?}/")] public IActionResult NoRest(string name) { ViewBag.Name = name; return View(); }

访问连接:

http://localhost:5006/route/norest/

可以看到页面没有任何显示:

image-20200603014235139

正常情况下,如果不对参数设置可空而且参数被我们当做目录的一部分时,不给值是会提示404。

1.3 路由约束

约束 示例 匹配项示例 说明
int {id:int} 123456789, -123456789 匹配任何整数
bool {active:bool} true, FALSE 匹配 true 或 false。 不区分大小写
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm 在固定区域性中匹配有效的 DateTime 值。 请参阅前面的警告。
decimal {price:decimal} 49.99, -1,000.01 在固定区域性中匹配有效的 decimal 值。 请参阅前面的警告。
double {weight:double} 1.234, -1,001.01e8 在固定区域性中匹配有效的 double 值。 请参阅前面的警告。
float {weight:float} 1.234, -1,001.01e8 在固定区域性中匹配有效的 float 值。 请参阅前面的警告。
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638 匹配有效的 Guid 值
long {ticks:long} 123456789, -123456789 匹配有效的 long 值
minlength(value) {username:minlength(4)} Rick 字符串必须至少为 4 个字符
maxlength(value) {filename:maxlength(8)} MyFile 字符串不得超过 8 个字符
length(length) {filename:length(12)} somefile.txt 字符串必须正好为 12 个字符
length(min,max) {filename:length(8,16)} somefile.txt 字符串必须至少为 8 个字符,且不得超过 16 个字符
min(value) {age:min(18)} 19 整数值必须至少为 18
max(value) {age:max(120)} 91 整数值不得超过 120
range(min,max) {age:range(18,120)} 91 整数值必须至少为 18,且不得超过 120
alpha {name:alpha} Rick 字符串必须由一个或多个字母字符(a-z,不区分大小写)组成。
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 字符串必须与正则表达式匹配。 请参阅有关定义正则表达式的提示。
required {name:required} Rick 用于强制在 URL 生成过程中存在非参数值

2. 路由统一前缀

在第一节中,我们介绍了如何使用RouteAttribute为控制器里的方法标记路由信息。有时候会出现这样的一个问题,一个控制器方法里可能会出现多个方法(Action)。通常情况下,我们要求一个控制器处理的请求应当有一个统一的前缀(或者称之为URL目录)。

那么,这种情况我们仍然继续使用 RouteAttribute,不过与之前不同的是,这次直接在控制器类上标记:

[Route("/Route")] public class RouteCtrTestController: Controller { }

这时候,在方法上如果添加了RouteAttribute,设置的路由信息如果不是以/ 开始,则会将该Action的路由配置加到Controller后面。如果是以/ 开始,则表示该路由是根路由。

如果没有设置RouteAttribute,则表示当前方法是处理控制器配置的路由的方法。

如果一个控制器里出现多个未设置RouteAttribute,则会出错。

示例代码如下:

[Route("/Route")] public class RouteCtrTestController: Controller { public int temp{get;set;} public IActionResult Index(int temp) { return Content($"你好{temp}"); } [Route("Demo")] public IActionResult Demo() { return Content($"你好 Demo"); } }

2. 总结

今天的内容比较短,这里介绍了一些路由的另一种用法,小伙伴们对此有个了解就可以了。下一篇将会到视图,开始准备带领大家做一个小项目啦。

  • C#
  • C#
  • web

扫一扫,分享到微信

【asp.net core 系列】3 视图以及视图与控制器
【asp.net core 系列】5 布局页和静态资源
  1. 0. 前言
  2. 1. 路由属性(Route Attribute)
    1. 1.1 如何设置
    2. 1.2 设置参数
    3. 1.3 路由约束
  3. 2. 路由统一前缀
  4. 2. 总结
© 2019-2025 Mr.Gao
Theme:hexo-theme-yilia-plus by Litten
晋ICP备2023000821号-1   
本站总访问量次 | 本站访客数人