一. Core Mvc

1.传统路由

  Core MVC中,默认会在 Startup类→Configure方法→UseMvc方法中,会有默认路由:routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); 等价于 app.UseMvcWithDefaultRoute();

(1). 参数解析说明

  name代表:路由名称, template代表:路由模板,可以在上面直接赋默认值,defaults代表:路由默认值;constraints代表:路由约束

(2). 多个路由

  多个路由默认从上往下解析,注意路由名称不能相同。

  比如: template: "{controller}/{action}/{id?}", 和 template: "{action}/{controller}/{id?}"两个路由规则共存,那么我既可以通过 https://localhost:44333/Index2/Home 访问页面,也可以通过 https://localhost:44333/Home/Index2 访问页面

                 //1.默认路由
//1.1 简版路由
{
routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
} //1.2 路由名称和多个参数的问题
{
routes.MapRoute(
name: "default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" }
);
routes.MapRoute(
name: "default2",
template: "{action}/{controller}/{id?}",
defaults: new { controller = "Home", action = "Index2" }
);
}

2. 属性路由

(1).Route[]

  Route可以单独作用Controller,也可以单独作用于action,当然也可以同时作用。

 (前提:注释掉全局的传统路由,当然也可以不注释,因为同时存在的话,属性路由的优先级高)

测试1:只在控制器上添加 [Route("Home2/{action}")],则可以通过【https://localhost:44333/Home2/Test1】正常访问.

测试2:只在Test1方法上添加 [Route("{controller}/Test111")], 则可以通过【https://localhost:44333/Home/Test111】正常访问

标记替换:直接以这种形式[Route("api/[controller]/[action]")]作用于控制器,该控制的匹配规则都将自动适配名称,该方法普遍用于WebApi上.

代码如下:

     [Route("Home2/{action}")]
public class HomeController : Controller
{ [Route("{controller}/Test111")]
public string Test1()
{
return "ok1";
}
}

(2).Http[Verb]

  Http[Verb]只能单独作用于action.

测试1:只在Test2方法上添加 [HttpGet("{controller}/Test22")],则可以通过【https://localhost:44333/Home/Test22】正常访问

测试2:只在Test2方法上添加 [HttpGet("{controller}/Test22")]和[HttpGet("{controller}/Test222")],则可以通过【https://localhost:44333/Home/Test22】 和【https://localhost:44333/Home/Test232】正常访问

代码如下:

 public class HomeController : Controller
{
[HttpGet("{controller}/Test22")]
[HttpGet("{controller}/Test222")]
public string Test2()
{
return "ok2";
} }

(3).多个属性路由的合并规则

A. Route和Route合并:Route可以同时作用在Controller和action,匹配规则是“叠加”;而且每个上面可以放多个,比如控制器上2个,action上3个,则有2*3=6种组合。

测试:控制器上添加:[Route("Home1/{action}")] 和 [Route("Home2/{action}")],

      action上添加:[Route("Test3")]、 [Route("Test33")]、 [Route("Test333")]

可以访问路径:https://localhost:44333/Home1/Test3/Test3

  https://localhost:44333/Home1/Test3/Test33

  https://localhost:44333/Home1/Test3/Test333 (访问不了,因为action上Route以/开头)

  https://localhost:44333/Home2/Test3/Test3

  https://localhost:44333/Home2/Test3/Test33

  https://localhost:44333/Home2/Test3/Test333 (访问不了,因为action上Route以/开头)

注:action上的属性路由以 / 或 ~/ 开头的路由模板不与应用于控制器的路由模板合并。

代码如下:

     [Route("Home1/{action}")]
[Route("Home2/{action}")]
public class HomeController : Controller
{
[Route("Test3")]
[Route("Test33")]
[Route("/Test333")]
public string Test3()
{
return "ok3";
} }

B. Route和Http[Verb]合并,匹配规则也是“叠加”,而且每个上面可以放多个,比如控制器上2个,action上3个,则有2*3=6种组合。

 测试:控制器上添加:[Route("Home1/{action}")] 和 [Route("Home2/{action}")],

            action上添加:[HttpGet("Test3")]、 [HttpGet("Test33")]、 [HttpGet("Test333")]

可以访问的路径和上面的一样,这里不再做重复测试了。

(4).扩展自定义属性路由

  新建类,实现IRouteTemplateProvider接口,继承Attribute类,然后就通过Template字段来声明自定义属性的路由规则了,如ypfAttribute类。

      /// <summary>
/// 自定义路由特性
/// </summary>
public class ypfAttribute : Attribute, IRouteTemplateProvider
{
public string Template => "api/[controller]/[action]"; /// <summary>
/// 属性排序
/// </summary>
public int? Order { get; set; } /// <summary>
/// 属性名
/// </summary>
public string Name { get; set; }

3.传统路由和属性路由共存

  通常情况下传统路由服务于Core MVC,属性路由服务于Restful Api,但如果二者共存的时候,属性路由的优先级更高,传统路由失效。

测试案例:打开传统路由【1.1】简版路由,然后在Index方法加[Route("kkk")], 这个时候

  (1).要想访问Index2页面,走的依旧是传统路由:https://localhost:44333/Home/Index2

  (2).要想访问Index页面,只能走属性路由:https://localhost:44333/kkk

注:这里是把特性加在Index方法上,所以请求地址中不能有控制器名称哦

代码如下:

4.区域路由(Area)

前提:必须给区域下的控制器加上特性标注区域名称!!!如: [Area("A1_Areas")]

方案一:

  有几个区域,则通过MapAreaRoute来添加几个路由,放在传统默认路由的前面。

         //3.1 有几个区域配置几个区域路由,并且放在默认路由的前面
{
//区域路由
routes.MapAreaRoute("myAreaRoute1", "A1_Areas", "{area}/{controller}/{action}/{id?}");
routes.MapAreaRoute("myAreaRoute2", "A2_Areas", "{area}/{controller}/{action}/{id?}"); //默认路由
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}"); }

方案二:(推荐!)

  利用MapRoute方法,添加一个含{area:exists}的路由,必须放在默认路由的后面!

                 //3.2 单独配置一个含area的路由,放在默认路由的后面
{ //默认路由
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}"); //区域路由(要放在默认路由的后面)
routes.MapRoute(
name: "default2",
template: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
}

测试:

  访问Home/Index 页面(上面什么特性不要加),里面的连接可以分别跳转到A1和A2区域下的页面。

二. Core WebApi

  默认情况下WebApi的路由规则是RestFul风格的,而且WebApi项目并没有全局注册传统路由,这种模式很不友好.通常我们有两类改造方案。

(前提补充:[Route]和[ApiController]要成对出现,可以同时和传统路由共存,优先级比传统路由高,但是[ApiController]不能单独出现,不能单独和传统路由共存;而 [Route]可以单独和全局路由共存)

方案一:全局配置,全局进行改造,在Configure方法中添加规则为:"api/{controller}/{action}/{id?}"和"api/{area:exists}/{controller}/{action}/{id?}"的全局路由和区域路由,则我们就可以通过上述路径进行访问了。

Core2.x版本

          app.UseMvc(routes =>
{
//全局路由
routes.MapRoute(
name: "default",
template: "api/{controller}/{action}/{id?}",
defaults: new { controller = "Second", action = "Test" }); //区域路由(对应区域下面的控制器一定要加 [Area("")])
routes.MapRoute(
name: "default2",
template: "api/{area:exists}/{controller}/{action}/{id?}"); //用于显示默认访问,这样直接打开https://localhost:44387/,就可以直接调用方法了。
//routes.MapRoute(
// name: "default3",
// template: "{controller}/{action}/{id?}",
// defaults: new { controller = "Second", action = "Test" });
});

Core3.x写法

   app.UseEndpoints(endpoints =>
{
//默认路由
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Admin}/{action=LoginIndex}/{id?}");
//pattern: "{controller=Demo}/{action=Index}/{id?}"); //区域路由(要放在默认路由的后面)
//注:必须以特性的形式在对应控制器上加上区域名称 [Area("XXXX")]
endpoints.MapControllerRoute(
name: "default2",
pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
});

方案二:不需要全局配置,在每个控制器的上面添加 [Route("api/[controller]/[action]")]和[ApiController],也可以达到同样的目的。

     [Route("api/[controller]/[action]")]
[ApiController]
public class SecondController : ControllerBase
{
[HttpGet]
public string Test()
{
return "ok";
}
[HttpGet]
public string Test2()
{
return "ok2";
}
[HttpPost]
public string Test3(UserInfor model)
{
return $"{model.userName}+{model.pwd}";
}
}

PS:在实际开发中,可以这两种方案相互结合进行使用。

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第二十一节:Asp.Net Core MVC和WebApi路由规则的总结和对比的更多相关文章

  1. asp.net core mvc 中间件之路由

    asp.net core mvc 中间件之路由 路由中间件 首先看路由中间件的源码 先用httpContext实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合 然后把路由上下文 ...

  2. ASP.NET Core MVC 配置全局路由前缀

    前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Ap ...

  3. 【转】ASP.NET Core MVC 配置全局路由前缀

    本文地址:http://www.cnblogs.com/savorboard/p/dontnet-IApplicationModelConvention.html作者博客:Savorboard 前言 ...

  4. asp.net core mvc剖析:路由

    在mvc框架中,任何一个动作请求都会被映射到具体控制器中的方法上,那框架是如何完成这样一个过程的,现在我们就来简单分析下流程. 我们紧跟上面的主题,任何一个请求都会交给处理管道进行处理,那mvc处理的 ...

  5. Pro ASP.NET Core MVC 第6版 第一章

    目录 第一章 ASP.NET Core MVC 的前世今生 ASP.NET Core MVC 是一个微软公司开发的Web应用程序开发框架,它结合了MVC架构的高效性和简洁性,敏捷开发的思想和技术和.N ...

  6. 详解 ASP.NET Core MVC 的设计模式

    MVC 是什么?它是如何工作的?我们来解剖它 在本节课中我们要讨论的内容: 什么是 MVC? 它是如何工作的? 什么是 MVC MVC 由三个基本部分组成 - 模型(Model),视图(View)和控 ...

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

    一.前言 1.本文主要内容 ASP.NET Core MVC路由工作原理概述 ASP.NET Core MVC带路径参数的路由示例 ASP.NET Core MVC固定前/后缀的路由示例 ASP.NE ...

  8. ASP.NET Core MVC的路由参数中:exists后缀有什么作用,顺便谈谈路由匹配机制

    我们在ASP.NET Core MVC中如果要启用Area功能,那么会看到在Startup类的Configure方法中是这么定义Area的路由的: app.UseMvc(routes => { ...

  9. ASP.NET Core 入门笔记4,ASP.NET Core MVC路由入门

    敲了一部分,懒得全部敲完,直接复制大佬的博客了,如有侵权,请通知我尽快删除修改 摘抄自https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-mvc ...

随机推荐

  1. mysql 5.7 创建用户报错ERROR 1364 (HY000): Field 'ssl_cipher' doesn't have a default value

    如: INSERT INTO user (host, user, authentication_string, select_priv, insert_priv, update_priv) VALUE ...

  2. layui 使用随记

    layui confir使用 不显示右上角关闭按钮 针对提示框内按钮指定操作 layer.confirm("这里填写提示信息", {closeBtn:0,icon: 0, titl ...

  3. Z从壹开始前后端分离【 .NET Core2.2/3.0 +Vue2.0 】框架之九 || 依赖注入IoC学习 + AOP界面编程初探

    本文梯子 本文3.0版本文章 更新 代码已上传Github+Gitee,文末有地址 零.今天完成的绿色部分 一.依赖注入的理解和思考 二.常见的IoC框架有哪些 1.Autofac+原生 2.三种注入 ...

  4. 如何使用npm的部分用法以及npm被墙的解决方法

    我们要明白我们使用的npm就是node中自带的包(模块)管理工具:借助NPM可以帮助我们快速安和管理依赖包,使Node与第三方模块之间形成了一个良好的生态系统. 我们可以直接输入npm,查看帮助引导: ...

  5. Docker配置yapi接口

    一.安装Docker 第一步:yum 包更新到最新 sudo yum update 第二步:安装需要的软件包 yum-util 提供yum-config-manager功能,另外两个是devicema ...

  6. SSM定时任务(spring3.0)

    SSM定时任务主要分为两部分 1.applicationContext.xml配置文件设置 设置如下: 在xmlns中添加:xmlns:task="http://www.springfram ...

  7. Winform中怎样获取项目图片资源并转换为Image对象

    场景 DevExpress的TreeList怎样给树节点设置图标: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10274554 ...

  8. Vue--过滤器、指令、插件

    常用下载js的网址: https://www.bootcdn.cn/ https://www.jsdelivr.com/ 一.过滤器 vue 允许自定义过滤器,用于格式化一些常见文本(如日期等). 1 ...

  9. 使用Wireshark进行DNS协议解析

    - 域名及解析过程 域名由一系列 - DNS协议报文格式 一次DNS过程包含一对请求报文和响应报文.请求和响应报文有统一的报文格式如下图: - DNS报文例子 一次DNS请求的过程: 包括请求和响应, ...

  10. GIL全局解释器锁、死锁、递归锁、线程队列

    目录 GIL全局解释锁 多线程的作用 测试计算密集型 IO密集型 死锁现象 递归锁 信号量(了解) 线程队列 GIL全局解释锁 GIL本质上是一个互斥锁. GIL是为了阻止同一个进程内多个进程同时执行 ...