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

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绑定式路由使用介绍

二、本教程环境信息

软件/环境 说明
操做系统 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-02javascript

三、前置知识

你可能须要的前置知识css

  • MVC框架/模式介绍

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

  • 正则表达式

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

2、ASP.NET Core MVC 路由简介

一、ASP.NET Core MVC路由工做原理概述

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

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

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

二、路由配置参数说明

参数名 说明
name 路由名称,不可重复
template 路由模板,可在模板中以{name}格式定义路由参数
defaults 配置路由参数默认值
constraints 路由约束

在路由配置中,MVC框架内置了两个参数,controller,action。
路由匹配经过后,须要根据这两个参数将当前请求交由对应的Controller+Action去处理。因此,这两个参数缺乏任何一个,都会致使路由没法正常工做。
一般咱们有两个选择:浏览器

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

3、ASP.NET Core MVC 路由示例

一、准备工做

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

  • 建立TutorialController

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

using System; using Microsoft.AspNetCore.Mvc; namespace Ken.Tutorial.Web.Controllers { public class TutorialController : Controller { } } 
  • 增长Action:Index
public IActionResult Index() { return Content("ASP.NET Core Tutorial by ken from ken.io"); } 
  • 增长Action:Welcome
public IActionResult Welcome(string name, int age) { return Content($"Welcome {name}(age:{age}) !"); } 

二、带路径参数的路由

路由配置:

routes.MapRoute(
        name: "TutorialPathValueRoute", template: "{controller}/{action}/{name}/{age}" ); 

此路由适配URL:

  • /tutorial/welcome/ken/20

不适配URL:

  • /tutorial/welcome/ken

若是咱们但愿不在路径中设置age,也能够被路由到,那么能够将age指定为可选参数,将模板中的{age}修改成{age?}便可

routes.MapRoute(
        name: "TutorialPathValueRoute", template: "{controller}/{action}/{name}/{age?}" ); 

此路由适配URL:

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

三、固定先后缀的路由

固定前缀路由配置:

routes.MapRoute(
    name: "TutorialPrefixRoute", template: "jiaocheng/{action}", defaults: new { controller = "Tutorial" } ); 

此路由适配URL:

  • /jiaocheng/index
  • /jiaocheng/welcome

因为路径参数中不包含controller参数,因此须要在默认值中指定。

固定后缀路由配置

routes.MapRoute(
    name: "TutorialSuffixRoute", template: "{controller}/{action}.html" ); 

此路由适配URL:

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

固定后缀的路由适用于伪静态等诉求
固定先后缀能够根据本身的需求结合起来使用。
固然,你也能够在路由模板中间设定固定值。

4、ASP.NET Core MVC 路由约束

一、路由约束介绍

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

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

using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Constraints; 

二、参数长度约束

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

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

咱们也能够直接在模板中配置路由约束:

routes.MapRoute(
    name: "TutorialLengthRoute2", template: "hello2/{name:maxlength(5)}/{age?}", defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" } ); 

三、参数范围约束

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

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

咱们也能够直接在模板中配置路由约束:

routes.MapRoute(
    name: "TutorialLengthRoute2", template: "hello2/{name}/{age:range(1,150)?}", defaults: new { controller = "Tutorial", action = "Welcome", name = "ken" } ); 

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

路由配置:

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到多个小写字母

咱们也能够直接在模板中配置路由约束:

routes.MapRoute(
    name: "TutorialRegexRoute2", template: "welcome2/{name:regex(@"k[a-z]*")}", defaults: new { controller = "Tutorial", Action = "Welcome" } ); 

五、自定义路由约束

一、建立自定义约束

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

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中不能包含,

二、路由配置

引入命名空间

using Ken.Tutorial.Web.Common; 

在ConfigureServices引入路由约束

public void ConfigureServices(IServiceCollection services) { //引入MVC模块 services.AddMvc(); //引入自定义路由约束 services.Configure<RouteOptions>(options => { options.ConstraintMap.Add("name", typeof(NameRouteConstraint)); }); } 

配置路由

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,

固然,按照惯例,依然能够在模板中配置路由约束

routes.MapRoute(
    name: "TutorialDiyConstraintRoute2", template: "diy2/{name:name}", defaults: new { controller = "Tutorial", action = "Welcome" } ); 

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

一、路由配置风格

  • 集中式配置

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

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

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

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

二、绑定式路由配置

在项目Controllers目中新建TestController.cs继承与Controller
并配置Action与路由

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")]为例,至关于生成了如下路由配置:

routes.MapRoute(
    name: "Default", template: "test/home", defaults: new { controller = "Test", action = "Index" } ); 

固然,咱们也能够在[Route]配置中使用模板参数,并且依然能够在模板中使用约束,自定义约束也没问题。

[Route("welcome/{name:name}")] public IActionResult Welcome(string name){ return Content($"Welcome {name} !"); } 

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

6、备注

一、附录

  • 本文代码示例

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


本文首发于个人独立博客: https://ken.io/note/asp.net-core-tutorial-mvc-route

相关文章
相关标签/搜索