第二十一节:Asp.Net Core MVC和WebApi路由规则的总结和对比
一. 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路由规则的总结和对比的更多相关文章
- asp.net core mvc 中间件之路由
asp.net core mvc 中间件之路由 路由中间件 首先看路由中间件的源码 先用httpContext实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合 然后把路由上下文 ...
- ASP.NET Core MVC 配置全局路由前缀
前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Ap ...
- 【转】ASP.NET Core MVC 配置全局路由前缀
本文地址:http://www.cnblogs.com/savorboard/p/dontnet-IApplicationModelConvention.html作者博客:Savorboard 前言 ...
- asp.net core mvc剖析:路由
在mvc框架中,任何一个动作请求都会被映射到具体控制器中的方法上,那框架是如何完成这样一个过程的,现在我们就来简单分析下流程. 我们紧跟上面的主题,任何一个请求都会交给处理管道进行处理,那mvc处理的 ...
- Pro ASP.NET Core MVC 第6版 第一章
目录 第一章 ASP.NET Core MVC 的前世今生 ASP.NET Core MVC 是一个微软公司开发的Web应用程序开发框架,它结合了MVC架构的高效性和简洁性,敏捷开发的思想和技术和.N ...
- 详解 ASP.NET Core MVC 的设计模式
MVC 是什么?它是如何工作的?我们来解剖它 在本节课中我们要讨论的内容: 什么是 MVC? 它是如何工作的? 什么是 MVC MVC 由三个基本部分组成 - 模型(Model),视图(View)和控 ...
- ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门
一.前言 1.本文主要内容 ASP.NET Core MVC路由工作原理概述 ASP.NET Core MVC带路径参数的路由示例 ASP.NET Core MVC固定前/后缀的路由示例 ASP.NE ...
- ASP.NET Core MVC的路由参数中:exists后缀有什么作用,顺便谈谈路由匹配机制
我们在ASP.NET Core MVC中如果要启用Area功能,那么会看到在Startup类的Configure方法中是这么定义Area的路由的: app.UseMvc(routes => { ...
- ASP.NET Core 入门笔记4,ASP.NET Core MVC路由入门
敲了一部分,懒得全部敲完,直接复制大佬的博客了,如有侵权,请通知我尽快删除修改 摘抄自https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-mvc ...
随机推荐
- httpclient超时时间设置及代理设置
超时时间 设置HttpClient的超时时间,非常有必要性,因为httpclient 默认超时时间很长,自己可以测试一下是多久,设置超时时间否则会影响自己系统的业务逻辑,例如阻塞系统,影响系统的吞吐量 ...
- SynchronusQueue
/** * 当向SynchronousQueue插入元素时,必须同时有个线程往外取 * SynchronousQueue是没有容量的,这是与其他的阻塞队列不同的地方 */ public class S ...
- ASP.NET Core基于K8S的微服务电商案例实践--学习笔记
摘要 一个完整的电商项目微服务的实践过程,从选型.业务设计.架构设计到开发过程管理.以及上线运维的完整过程总结与剖析. 讲师介绍 产品需求介绍 纯线上商城 线上线下一体化 跨行业 跨商业模式 从0开始 ...
- vue-品牌管理案例-指令和过滤器
过滤器的基本使用 定义一个过滤器 <div id="app"> <p>{{ msg | msgFormat('疯狂+1', '123') | test }} ...
- Python 爬取猫眼电影《无名之辈》并对其进行数据分析
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 罗昭成 PS:如有需要Python学习资料的小伙伴可以加点击下方链接 ...
- opencv::BackgroundSubtraction基本原理
背景消除 BS算法 - 图像分割(GMM – 高斯混合模型) - 机器学习(KNN –K个最近邻) BackgroundSubtractor (父类) - BackgroundSubtractorMO ...
- ubuntu 安装elasticsearch
elasticsearch简介 环境准备 elasticsearch:7.0.0 kibana :7.0.0 安装 1.新创建普通用户 elasticsearch不能用root账号 ...
- PHP比较两个数组的差异
array_diff($arr, $arr1); //比较数组差异 $arr = [1,2,3,4]; $arr1 = [1,2,3]; $diff = array_diff($arr, $arr1) ...
- python爬虫中文乱码问题(request方式爬取)
https://blog.csdn.net/guoxinian/article/details/83047746 req = requests.get(url)返回的是类对象 其包括的属性有: r ...
- semantic功能介绍
semantic功能介绍 gnu Semantic Manual 1,代码自动补全 3,代码导航 启动semantic功能:(semantic-mode 1) 1,Semantic mode 是辅助模 ...