【asp.net core 系列】4. 更高更强的路由
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 后,如果不出意外可以看到跟下图类似的界面:

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

可以看到提示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

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

尝试变更name的值,可以发现网页中的值也发生了变化,证明我们可以获取到这个值。
1.2.2 当做请求目录的一部分
在上一小节中,没有对参数做任何操作,以查询参数的形式传递。在这一篇,我们可以把参数设置为请求的一部分,像目录那样,修改上一节示例代码为:
[Route("/route/norest/{name}/")]
public IActionResult NoRest(string name)
{
    ViewBag.Name = name;
    return View();
}
请求方式:
http://localhost:5006/route/norest/1232

修改连接中的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/
可以看见:

设置为可空,也就是参数可以不传:
[Route("/route/norest/{name?}/")]
public IActionResult NoRest(string name)
{
    ViewBag.Name = name;
    return View();
}
访问连接:
http://localhost:5006/route/norest/
可以看到页面没有任何显示:

正常情况下,如果不对参数设置可空而且参数被我们当做目录的一部分时,不给值是会提示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. 总结
今天的内容比较短,这里介绍了一些路由的另一种用法,小伙伴们对此有个了解就可以了。下一篇将会到视图,开始准备带领大家做一个小项目啦。
更多内容烦请关注我的博客《高先生小屋》

【asp.net core 系列】4. 更高更强的路由的更多相关文章
- asp.net core 系列 18 web服务器实现
		一. ASP.NET Core Module 在介绍ASP.NET Core Web实现之前,先来了解下ASP.NET Core Module.该模块是插入 IIS 管道的本机 IIS 模块(本机是指 ... 
- asp.net core 系列 16 Web主机 IWebHostBuilder
		一.概述 在asp.net core中,Host主机负责应用程序启动和生存期管理.host主机包括Web 主机(IWebHostBuilder)和通用主机(IHostBuilder).Web 主机是适 ... 
- 技术的正宗与野路子  c#, AOP动态代理实现动态权限控制(一)  探索基于.NET下实现一句话木马之asmx篇  asp.net core 系列 9 环境(Development、Staging 、Production)
		黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ... 
- WPF中的常用布局      栈的实现    一个关于素数的神奇性质      C# defualt关键字默认值用法   接口通俗理解    C# Json序列化和反序列化    ASP.NET CORE系列【五】webapi整理以及RESTful风格化
		WPF中的常用布局 一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ... 
- Ajax跨域问题及解决方案  asp.net core 系列之允许跨越访问(Enable Cross-Origin Requests:CORS)   c#中的Cache缓存技术   C#中的Cookie   C#串口扫描枪的简单实现   c#Socket服务器与客户端的开发(2)
		Ajax跨域问题及解决方案 目录 复现Ajax跨域问题 Ajax跨域介绍 Ajax跨域解决方案 一. 在服务端添加响应头Access-Control-Allow-Origin 二. 使用JSONP ... 
- 【目录】asp.net core系列篇
		随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ... 
- 【asp.net core 系列】 1  带你了解一下asp.net core
		0. 前言 这是一个新的系列,名字是<ASP.NET Core 入门到实战>.这个系列主讲ASP.NET Core MVC,辅助一些前端的基础知识(能用来实现我们需要的即可,并非主讲).同 ... 
- 【asp.net core 系列】6 实战之 一个项目的完整结构
		0. 前言 在<asp.net core 系列>之前的几篇文章中,我们简单了解了路由.控制器以及视图的关系以及静态资源的引入,让我们对于asp.net core mvc项目有了基本的认识. ... 
- 【asp.net core 系列】10  实战之ActionFilter
		0.前言 在上一篇中,我们提到了如何创建一个UnitOfWork并通过ActionFilter设置启用.这一篇我们将简单介绍一下ActionFilter以及如何利用ActionFilter,顺便补齐一 ... 
随机推荐
- Redis系列(七)Redis面试题
			Redis 系列: Redis系列(一)Redis入门 Redis系列(二)Redis的8种数据类型 Redis系列(三)Redis的事务和Spring Boot整合 Redis系列(四)Redis配 ... 
- css3及css技巧
			左右对齐: 
- SpringBoot+SpringCloud面试题整理
			什么是SpringBoot?1.用来简化spring初始搭建和开发过程使用特定的方式进行配置(properties或者yml文件)2.创建独立的spring引用程序main方法运行3.嵌入Tomcat ... 
- Unity3D中UGUI不使用DOTween制作渐隐渐现效果
			在做UI后期设计时,我们可能要对UI做一些特效,这篇文章我们来学习下如何在Unity3d中对实现渐隐渐现的效果, 首先我们看下Unity New UI即UGUI中渐隐渐现的做法. 观察我们会发现Uni ... 
- zabbix配置主动式监控的步骤(原创)
			步骤如下: 1.克隆模板.命名新的模板名,并点击"监控项",全选,批量更新时第一个“类型”打勾,客户端改为主动式: 2.添加客户端或更改原有的模板为新模板(服务器端添加客户端时的配 ... 
- mysql小白系列_10 mysql主从复制原理
			1.如何解决主从复制延迟的问题? (1)主从复制原理 http://www.cnblogs.com/jenvid/p/8410922.html 1.salve执行slave start,salve服务 ... 
- Netty框架问题记录1--多线程下批量发送消息导致消息被覆盖
			业务背景 项目是基于Netty实现的实时课堂项目,课堂中老师需要对试卷进行讲解,则老师向服务器发送一个打开试卷信息的请求,服务器获取试卷信息,将试卷信息发送给所有的客户端(学生和老师). 发送给学生的 ... 
- hrb
- 19-6 通过t-sql实现约束
			------------------------------------------------------------------------ --通过t-sql语句来创建约束 ---------- ... 
- linux添加策略路由python脚本(待完善)
			#! _*_ coding:utf-8 _*_ import os,sys,re,fileinput,socket device_list = [] ip_list = [] ip_end = [] ... 
