一. 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. Implement Custom Business Classes and Reference Properties 实现自定义业务类和引用属性(XPO)

    In this lesson, you will learn how to implement business classes from scratch. For this purpose, the ...

  2. JS基础语法---函数---介绍、定义、函数参数、返回值

    函数: 把一坨重复的代码封装,在需要的时候直接调用即可 函数的作用: 代码的重用 函数需要先定义,然后才能使用 函数名字:要遵循驼峰命名法 函数一旦重名,后面的会把前面的函数覆盖 Ctrl +鼠标左键 ...

  3. WebLogic任意文件上传漏洞复现与分析 -【CVE-2018-2894 】

    CVE-2018-2894 漏洞影响版本:10.3.6.0, 12.1.3.0, 12.2.1.2, 12.2.1.3 下载地址:http://download.oracle.com/otn/nt/m ...

  4. MD5哈希算法及其原理

    - MD5功能 MD5算法对任意长度的消息输入,产生一个128位(16字节)的哈希结构输出.在处理过程中,以512位输入数据块为单位. - MD5用途及特征 MD5通常应用在以下场景: 1.防篡改,保 ...

  5. QNetworkRequest加Authorization头,适应Rest风格的API

    Rest是无状态的.Rest的请求之间不应该有依赖,在调用一个请求前,不需要一定要去提前调用另外一个请求.Rest里面不应该有 session,特别是Rest请求不应该保存信息在sesssion里,以 ...

  6. 如何开发优质的 Flutter App:Flutter App 软件测试指南

    继上一场GitChat文章发布之后,博主又为朋友们带来另一场Chat.这一次我们主要聊一聊Flutter App的测试环节. 众所周知,应用的功能越多,手动测试的难度就越大.一套完整的自动化测试将帮助 ...

  7. [b0037] python 归纳 (二二)_多进程数据共享和同步_管道Pipe

    # -*- coding: utf-8 -*- """ 多进程数据共享 管道Pipe 逻辑: 2个进程,各自发送数据到管道,对方从管道中取到数据 总结: 1.只适合两个进 ...

  8. mySql创建带解释的表及给表和字段加注释的实现代码

    1.创建带解释的表 CREATE TABLE test_table( t_id INT(11) PRIMARY KEY AUTO_INCREMENT COMMENT '设置主键自增', t_name ...

  9. 苹果手机Chrome浏览器显示input:disabled时字体颜色总是为浅灰色

    今天被测试人员提了个bug:苹果手机浏览器(Chrome)打开h5,控件在input:disabled的样式始终是浅灰色,要求改成黑色.测试对比:1.在多个pc浏览器上浏览input:disabled ...

  10. [日常] git版本回退

    还没有push到远程的时候,版本回退的测试如下 先克隆一个空的测试仓库,这是我自己在gitlab里创建的空仓库git clone http://192.168.1.114:8090/admintsh/ ...