Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门

ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门

作者头像
KenTalk
发布于 2020-01-19 11:22:30
发布于 2020-01-19 11:22:30
1.5K00
代码可运行
举报
文章被收录于专栏:Ken的杂谈Ken的杂谈
运行总次数:0
代码可运行

一、前言

1、本文主要内容

  • ASP.NET Core MVC路由工作原理概述
  • ASP.NET Core MVC带路径参数的路由示例
  • ASP.NET Core MVC固定前/后缀的路由示例
  • ASP.NET Core MVC正则表达式匹配路由示例
  • ASP.NET Core MVC路由约束与自定义路由约束
  • ASP.NET Core MVC RouteAttribute绑定式路由使用介绍

2、本教程环境信息

软件/环境

说明

操作系统

Windows 10

SDK

2.1.401

ASP.NET Core

2.1.3

IDE

Visual Studio Code 1.27

浏览器

Chrome 69

本篇代码基于上一篇进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02

3、前置知识

你可能需要的前置知识

  • MVC框架/模式介绍

https://baike.baidu.com/item/mvc

  • 正则表达式

http://www.runoob.com/regexp/regexp-tutorial.html

二、ASP.NET Core MVC 路由简介

1、ASP.NET Core MVC路由工作原理概述

ASP.NET Core MVC路由的作用就是将应用接收到请求转发到对应的控制器去处理。

应用启动的时候会将路由中间件(RouterMiddleware)加入到请求处理管道中,并将我们配置好的路由加载到路由集合(RouteCollection)中。当应用接收到请求时,会在路由管道(路由中间件)中执行路由匹配,并将请求交给对应的控制器去处理。

另外,需要特别注意的是,路由的匹配顺序是按照我们定义的顺序从上之下匹配的,遵循是的先配置先生效的原则。

2、路由配置参数说明

参数名

说明

name

路由名称,不可重复

template

路由模板,可在模板中以{name}格式定义路由参数

defaults

配置路由参数默认值

constraints

路由约束

在路由配置中,MVC框架内置了两个参数,controller,action。

路由匹配通过后,需要根据这两个参数将当前请求交由对应的Controller+Action去处理。所以,这两个参数缺少任何一个,都会导致路由无法正常工作。

通常我们有两个选择:

  • 在template中指定{controller},{action}参数
  • 在默认值中为controller、action指定默认值

三、ASP.NET Core MVC 路由示例

1、准备工作

为了方便我们进行测试,我们先准备好承接路由的Controller&Action

  • 创建TutorialController

在Controllers文件夹下新增控制器TutorialController.cs并继承于Controller

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using Microsoft.AspNetCore.Mvc;

namespace Ken.Tutorial.Web.Controllers
{
    public class TutorialController : Controller
    {

    }
}
  • 增加Action:Index
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public IActionResult Index()
{
    return Content("ASP.NET Core Tutorial by ken from ken.io");
}
  • 增加Action:Welcome
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public IActionResult Welcome(string name, int age)
{
    return Content($"Welcome {name}(age:{age}) !");
}

2、带路径参数的路由

路由配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
        name: "TutorialPathValueRoute",
        template: "{controller}/{action}/{name}/{age}"
    );

此路由适配URL:

  • /tutorial/welcome/ken/20

不适配URL:

  • /tutorial/welcome/ken

如果我们希望不在路径中设置age,也可以被路由到,那么可以将age指定为可选参数,将模板中的{age}修改为{age?}即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
        name: "TutorialPathValueRoute",
        template: "{controller}/{action}/{name}/{age?}"
    );

此路由适配URL:

  • /tutorial/welcome/ken/20
  • /tutorial/welcome/ken
  • /tutorial/welcome/ken?age=20

3、固定前后缀的路由

固定前缀路由配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialPrefixRoute",
    template: "jiaocheng/{action}",
    defaults: new { controller = "Tutorial" }
);

此路由适配URL:

  • /jiaocheng/index
  • /jiaocheng/welcome

由于路径参数中不包含controller参数,所以需要在默认值中指定。

固定后缀路由配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialSuffixRoute",
    template: "{controller}/{action}.html"
);

此路由适配URL:

  • /tutorial/index.html
  • /tutorial/welcome.html
  • /home/index.html
  • /home/time.html

固定后缀的路由适用于伪静态等诉求

固定前后缀可以根据自己的需求结合起来使用。

当然,你也可以在路由模板中间设定固定值。

四、ASP.NET Core MVC 路由约束

1、路由约束介绍

路由约束主要是用于约束路由参数,在URL格式满足路有模板要求之后,进行参数检查。如果参数不满足路由约束,那么依然会返回未匹配该路由。最常用的可能就是参数类型校验、参数长度校验、以及通过正则满足的复杂校验。

在开始之前需要在Startup.cs中引用相关命名空间

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Constraints;

2、参数长度约束

路由配置:约束name长度不能>5

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialLengthRoute",
    template: "hello/{name}/{age?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" },
    constraints: new { name = new MaxLengthRouteConstraint(5) }
);

此路由适配

  • /hello
  • /hello/ken
  • /hello/ken/1000

次路由不适配

  • /hello/kenaaaa

我们也可以直接在模板中配置路由约束:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialLengthRoute2",
    template: "hello2/{name:maxlength(5)}/{age?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" }
);

3、参数范围约束

路由配置:约束 1<=age<=150

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialLengthRoute",
    template: "hello/{name}/{age?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" },
    constraints: new {  age = new CompositeRouteConstraint(new IRouteConstraint[] { 
                            new IntRouteConstraint(), 
                            new MinRouteConstraint(1), 
                            new MaxRouteConstraint(150) }) }
);

此路由适配:

  • /hello/ken/1
  • /hello/ken/150

此路由不适配

  • /hello/ken/1000

我们也可以直接在模板中配置路由约束:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialLengthRoute2",
    template: "hello2/{name}/{age:range(1,150)?}",
    defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" }
);

4、带有正则表达式约束的路由

路由配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialRegexRoute",
    template: "welcome/{name}",
    defaults: new { controller = "Tutorial", Action = "Welcome" },
    constraints: new { name = @"k[a-z]*" }
);

此路由适配:

  • /welcome/k
  • /welcome/ken
  • /welcome/kevin

此路由不适配

  • /welcome/k1
  • /welcome/keN
  • /welcome/tom

这里我们用正则表达式约束了参数name,必须通过正则k[a-z]*匹配通过,即:以小写字母k开头,且后续可跟0到多个小写字母

我们也可以直接在模板中配置路由约束:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialRegexRoute2",
    template: "welcome2/{name:regex(k[a-z]*)}",
    defaults: new { controller = "Tutorial", Action = "Welcome" }
);

5、自定义路由约束

1、创建自定义约束

在项目根目录创建目录Common,并在目录创建类:NameRouteConstraint.cs,然后实现接口:IRouteConstraint

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace Ken.Tutorial.Web.Common
{
    public class NameRouteConstraint : IRouteConstraint
    {
        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            string name = values["name"]?.ToString();
            if (name == null) return true;
            if (name.Length > 5 && name.Contains(",")) return false;
            return true;
        }
    }
}

这里我们约束当name长度>5时,name中不能包含,

2、路由配置

引入命名空间

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using Ken.Tutorial.Web.Common;

在ConfigureServices引入路由约束

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public void ConfigureServices(IServiceCollection services)
    {
        //引入MVC模块
        services.AddMvc();

        //引入自定义路由约束
        services.Configure<RouteOptions>(options =>
        {
            options.ConstraintMap.Add("name", typeof(NameRouteConstraint));
        });
    }

配置路由

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialDiyConstraintRoute",
    template: "diy/{name}",
    defaults: new { controller = "Tutorial", action = "Welcome" },
    constraints: new { name = new NameRouteConstraint() }
);

此路由适配:

  • /diy/ken
  • /diy/ken,
  • /diy/kenny

此路由不适配

  • /diy/kenny,

当然,按照惯例,依然可以在模板中配置路由约束

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "TutorialDiyConstraintRoute2",
    template: "diy2/{name:name}",
    defaults: new { controller = "Tutorial", action = "Welcome" }
);

五、ASP.NET Core MVC 绑定式路由配置

1、路由配置风格

  • 集中式配置

前面章节提到的路由配置都是在Startup类中进行的集中式路由配置,集中配置的路由,除了template中没有配置{controller}参数,默认都是对所有控制器(Controller)生效的。这种集中配置的方式一般我们只要配置一个默认路由,其他情况我们只需要不满足默认模板的情况下进行配置即可。尤其是对URL没有友好度要求的应用,例如:后台管理系统

  • 分散式配置/绑定式配置

对于集中式路由配置的方式,如果某个Controller/Action配置了特殊路由,对于代码阅读就会不太友好。不过没关系,ASP.NET Core MVC也提供了RouteAttribute可以让我们在Controller或者Action上直接指定路由模板。

不过要强调的是,一个控制器只能选择其中一种路由配置,如果控制器标记了RouteAttribute进行路由配置,那么集中式配置的路由将不对其生效。

2、绑定式路由配置

在项目Controllers目中新建TestController.cs继承与Controller

并配置Action与路由

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System;
using Microsoft.AspNetCore.Mvc;

namespace Ken.Tutorial.Web.Controllers
{
    [Route("/test")]
    public class TestController : Controller
    {
        [Route("")]
        [Route("/test/home")]
        public IActionResult Index()
        {
            return Content("ASP.NET Core RouteAttribute test by ken from ken.io");
        }

        [Route("servertime")]
        [Route("/t/t")]
        public IActionResult Time(){
            return Content($"ServerTime:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} - ken.io");
        }
    }
}

配置项

说明

Route(“/test”)

表示该Controller访问路由前缀为/test,必须以/开头

Route(“”)

表示以Controller的路由配置为前缀访问该Action;可以通过/test路由到该Action

Route(“/test/home”)

表示忽略Controller的路由配置;可以通过/test/home路由到该Action

Route(“servertime”)

表示以Controller的路由配置为前缀访问该Action;可以通过/test/servertime路由到该Action

Route(“/t/t”)

表示忽略Controller的路由配置;可以通过/t/t路由到该Action

RouteAttribute中配置的参数,就相当于我们集中式配置中的路由模板(template),最终框架还是帮我们初始化成路由规则,以Route(“/test/home”)为例,相当于生成了以下路由配置:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
routes.MapRoute(
    name: "Default",
    template: "test/home",
    defaults: new { controller = "Test", action = "Index" }
);

当然,我们也可以在Route配置中使用模板参数,而且依然可以在模板中使用约束,自定义约束也没问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[Route("welcome/{name:name}")]
public IActionResult Welcome(string name){
    return Content($"Welcome {name} !");
}

最大的区别就是不能定义默认值了,可能也不需要了,你说是吧。^_^

六、备注

1、附录

  • 本文代码示例

https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-03

  • 本文参考

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/routing?view=aspnetcore-2.1


本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/09/25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ASP.NET Core 入门教程 2、使用ASP.NET Core MVC框架构建Web应用
ASP.NET Core 默认集成了DI。所有官方模块的引入都要使用DI的方式引入。
KenTalk
2018/10/03
1.5K0
ASP.NET Core 入门教程 2、使用ASP.NET Core MVC框架构建Web应用
构建可读性更高的 ASP.NET Core 路由
  不知你在平时上网时有没有注意到,绝大多数网站的 URL 地址都是小写的英文字母,而我们使用 .NET/.NET Core MVC 开发的项目,因为在 C# 中类和方法名采用的是 Pascal 命名规范,根据 .NET 框架默认的路由规则,项目的 URL 地址会呈现出大小写混合的情况。对于强迫症来说,这种情况绝对不能忍,当然,由于整个项目的 URL 地址大小写混合显示,也无法更清晰的向用户、浏览器表达出当前页面的功能。那么,这篇文章就来介绍下,如何调整我们的 ASP.NET Core 项目的路由规则,从而使我们项目的 URL 地址可读性更高。
程序员宇说
2019/07/31
6800
ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案
ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不大,但从内部运行方式上来说,差别还是很大的。上一篇详细介绍了原版路由方案的运行机制,本文仍然通过一幅图来了解一下新版的运行机制,最后再总结一下二者的异同点。(ASP.NET Core 系列目录)
FlyLolo
2019/02/20
7220
ASP.NET Core 入门教程 9、ASP.NET Core 中间件(Middleware)入门
本篇代码以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
KenTalk
2019/04/01
1.3K0
ASP.NET Core 入门教程 9、ASP.NET Core 中间件(Middleware)入门
【asp.net core 系列】4. 更高更强的路由
在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转。那么,我们回过头来,再看看路由的一些其他用法。
程序员小高
2020/06/09
6440
ASP.NET MVC编程——路由
框架自动生成的路由配置 上图中,路由配置文件为App_Start文件夹下的RouteConfig.cs。 代码如下: public class RouteConfig { public
甜橙很酸
2018/03/30
1.8K0
ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门
本篇代码基于以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
KenTalk
2018/11/09
2.3K0
ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门
mvc网站迁移.net core记录
ConfigureServices方法中配置即可,详情见院长文章 http://www.cnblogs.com/dudu/p/5879913.html
易墨
2018/09/14
7040
mvc网站迁移.net core记录
ASP.NET Core 入门教程 8、ASP.NET Core + Entity Framework Core 数据访问入门
本篇代码以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
KenTalk
2018/12/29
2.3K0
ASP.NET Core 入门教程 8、ASP.NET Core + Entity Framework Core 数据访问入门
路由
    路由提供了Route类作为IRouter的标准实现。当调用RouteAsync方法时,Route使用路由模板语法定义匹配URL路径的模式,当调用GetVirtualPath方法时,Route会使用相同的路由模板生成URL。
莫问今朝
2018/08/31
9600
ASP.NET MVC5高级编程 ——(5)路由
这章呢,我们开始讲ASP.NET MVC5中的路由机制,在这之前,先提一下URL(Uniform Resource Locator)-- 统一资源定位符。需要注意的是,这里的“资源”这个词,是一个抽象的概念,既可以指一个文件,也可以指一个方法、一个类或是一段代码。由此我们引出了路由的主要用途:
浩Coding
2019/07/03
2.1K0
【ASP.NET Core 基础知识】--路由和请求处理--路由概念(一)
在Web应用中,路由是一个至关重要的概念,它负责将用户的请求映射到相应的处理程序,以确保正确的页面或资源被呈现给用户。通过将用户请求与适当的处理程序关联起来,使得应用能够以有序和可维护的方式响应用户的操作。
喵叔
2024/01/18
5530
ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler)
本文通过一张图来看一下路由的配置以及请求处理的机制。(ASP.NET Core 系列目录)
FlyLolo
2019/02/20
4530
ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门
本篇代码以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
KenTalk
2018/11/12
2.9K0
ASP.NET Core 入门教程 6、ASP.NET Core MVC 视图布局入门
ASP.NET MVC路由扩展:路由映射
上周我写了三篇文章(一、二、三)详细地介绍了ASP.NET的路由系统。ASP.NET的路由系统旨在通过注册URL模板与物理文件之间的映射进而实现请求地址与文件路径之间的分离,但是对于ASP.NET MVC应用来说,请求的目标不再是一个具体的物理文件,而是定义在某个Controller类型中的Action方法。出于自身路由特点的需要,ASP.NET对ASP.NET的路由系统进行了相应的扩展。 目录 一、基本路由映射 二、实例演示:注册路由映射与查看路由信息 三、基于A
蒋金楠
2018/01/15
1.4K0
ASP.NET MVC路由扩展:路由映射
基于ASP.NET core的MVC站点开发笔记 0x01
先到上面提供的下载地址,下载对应平台的dotnet装上,然后在命令行窗口输入dotnet --version查看输出是否安装成功。
CN_Simo
2020/07/07
8880
《ASP.ENT Core 与 RESTful API 开发实战》(第3章)-- 读书笔记(中)
当我们需要获取数据时,通常的做法是实例化依赖的类,然后调用类里面的方法,但是这种依赖方式会增加调用方和被调用方之间的耦合,也会增加应用程序维护成本及灵活性,同时增加了单元测试的难度
郑子铭
2021/01/13
1.2K0
《ASP.ENT Core 与 RESTful API 开发实战》(第3章)-- 读书笔记(中)
[译]Asp.net MVC 之 Contorllers(二)
URL路由模块 取代URL重写 路由请求 URL路由模块的内部结构 应用程序路由 URL模式和路由 定义应用程序路由 处理路由 路由处理程序 处理物理文件请求 防止路由定义的URL 属性路由  书接上回[译]Asp.net MVC 之 Contorllers(一) URL 路由HTTP模块通过获取 URL,然后调用合适的执行方法处理进来的请求。URL 路由 HTTP 模块取代了旧版本 ASP.NET 的 URL 重写功能。URL 重写的核心包括获取请求、解析原始 URL 以及指导 HTTP 运行时环境服务于
数据分析
2018/03/01
1.9K0
[译]Asp.net MVC 之 Contorllers(二)
ASp.NET MVC 路由「建议收藏」
ASP.NET MVC Route—转发请求: 1.客户端发起请求 2.到达IIS 3.转发到程序集 4.经过一个路由匹配–转发到匹配的控制器中 5.匹配的action去处理
全栈程序员站长
2022/09/15
5050
Asp.Net MVC2.0 Url 路由入门---实例篇
     本篇主要讲述Routing组件的作用,以及举几个实例来学习Asp.Net MVC2.0 Url路由技术。
老马
2022/05/10
4110
推荐阅读
相关推荐
ASP.NET Core 入门教程 2、使用ASP.NET Core MVC框架构建Web应用
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验