ASP.NET Core中的路由
传统路由
app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
MapControllerRoute用于创建单个路由。 单个路由命名为 default
路由 。大多数具有控制器和视图的应用都使用类似 default
路由的路由模板。
之所以称为传统路由,是因为它为 URL 路径建立了一个约定:
使用默认路由进行传统路由可以创建应用,而无需为每个操作提出新的 URL 模式。 对于具有 CRUD 样式操作的应用,跨控制器的 URL 保持一致:
- 第一个路径段
{controller=Home}
映射到控制器名称。 - 第二段
{action=Index}
映射到操作名称。 - 第三段
{id?}
用于可选id
。{id?}
中的?
使其成为可选。id
用于映射到模型实体。 -
此映射:
- 仅基于控制器和操作名称。
- 不基于命名空间、源文件位置或方法参数。
- 有助于简化代码。
- 使 UI 更具可预测性。
路由模板 "{controller=Home}/{action=Index}/{id?}"
匹配URL路径,例如
/Products/Details/5。在请求的URL中,如果不提供控制器名称,则使用默认的Home页面,操作默认为Index.例如 http://127.0.0.1:10050/,http://127.0.0.1:10050/Home,http://127.0.0.1:10050/Home/Index 这三个请求返回的都是同一个页面。
简便方法:app.MapDefaultControllerRoute();可替换上一个设置路由方案。
大多数应用应选择基本的描述性路由方案,让 URL 有可读性和意义。 默认传统路由 {controller=Home}/{action=Index}/{id?}
:
- 支持基本的描述性路由方案。
- 是基于 UI 的应用的有用起点。
- 是许多 Web UI 应用所需的唯一路由模板。 对于较大的 Web UI 应用,通常只需要使用区域的另一个路由。
传统路由顺序
常规路由仅匹配应用定义的操作和控制器的组合。 这是为了简化传统路由重叠的情况。 使用 MapControllerRoute、MapDefaultControllerRoute 和 MapAreaControllerRoute 添加路由会根据调用它们的顺序自动为其终结点分配一个顺序值。 来自较早出现的路由的匹配具有更高的优先级。 传统路由依赖于顺序。 一般情况下,具有区域的路由应放在路由表中靠前的位置,因为它们比没有区域的路由更具体。 具有 catch-all 路由参数的专用传统路由(例如 {*article}
)会使某个路由变得太贪婪,也就是说,它会匹配你想要使用其他路由来匹配的 URL。 将贪婪路由放在路由表中靠后的位置可解决此问题。
属性路由
API 的属性路由REST
REST API 应使用属性路由将应用的功能建模为一组资源,其中操作由 HTTP 谓词表示。
属性路由使用一组属性将操作直接映射到路由模板。如下示例:
public class HomeController : Controller
{[Route("")][Route("Home")][Route("Home/Index")][Route("Home/Index/{id?}")]public IActionResult Index(int? id){return ControllerContext.MyDisplayRouteInfo(id);}[Route("Home/About")][Route("Home/About/{id?}")]public IActionResult About(int? id){return ControllerContext.MyDisplayRouteInfo(id);}
}
这里可以看到属性路由需要更多输入才能指定路由。 传统默认路由会更简洁地处理路由。 但是,属性路由允许并需要精确控制应用于每项操作的路由模板。
这里我们注意到控制器和操作名称在操作匹配中不起作用,除非使用标记替换。如下示例:
public class HomeController : Controller
{[Route("")][Route("Home")][Route("[controller]/[action]")]public IActionResult Index(){return ControllerContext.MyDisplayRouteInfo();}[Route("[controller]/[action]")]public IActionResult About(){return ControllerContext.MyDisplayRouteInfo();}
}
也可直接将标记 [Route("[controller]/[action]")]
应用于控制器:
[Route("[controller]/[action]")]
public class HomeController : Controller
{[Route("~/")][Route("/Home")][Route("~/Home/Index")]public IActionResult Index(){return ControllerContext.MyDisplayRouteInfo();}public IActionResult About(){return ControllerContext.MyDisplayRouteInfo();}
}
在前面的代码中,Index
方法模板必须将 /
或 ~/
预置到路由模板。 应用于操作的以 /
或 ~/
开头的路由模板不与应用于控制器的路由模板合并。
保留的路由名称
以下关键字是使用控制器或 Razor Pages 时保留的路由参数名称:
action
area
controller
handler
page
-
在 Razor 视图或 Razor 页面的上下文中保留以下关键字:
-
page
-
using
-
namespace
-
inject
-
section
-
inherits
-
model
-
addTagHelper
-
removeTagHelper
不应将这些关键字用于链接生成、模型绑定参数或上层属性。
HTTP 谓词模板
ASP.NET Core 具有以下 HTTP 谓词模板:
- [HttpGet]
- [HttpPost]
- [HttpPut]
- [HttpDelete]
- [HttpHead]
- [HttpPatch]
路由模板
ASP.NET Core 具有以下路由模板:
- 所有HTTP谓词模板都是路由模板。
- [Route]
使用 Http 谓词属性的属性路由
[Route("api/[controller]")]
[ApiController]
public class Test2Controller : ControllerBase
{[HttpGet] // GET /api/test2public IActionResult ListProducts(){return ControllerContext.MyDisplayRouteInfo();}[HttpGet("{id}")] // GET /api/test2/xyzpublic IActionResult GetProduct(string id){return ControllerContext.MyDisplayRouteInfo(id);}[HttpGet("int/{id:int}")] // GET /api/test2/int/3public IActionResult GetIntProduct(int id){return ControllerContext.MyDisplayRouteInfo(id);}[HttpGet("int2/{id}")] // GET /api/test2/int2/3public IActionResult GetInt2Product(int id){return ControllerContext.MyDisplayRouteInfo(id);}
}
REST API 应使用属性路由将应用的功能建模为一组资源,其中操作由 HTTP 谓词表示。 也就是说,对同一逻辑资源执行的许多操作(例如,GET 和 POST)都使用相同 URL。 属性路由提供了精心设计 API 的公共终结点布局所需的控制级别。
组合属性路由
若要使属性路由减少重复,可将控制器上的路由属性与各个操作上的路由属性合并。 控制器上定义的所有路由模板均作为操作上路由模板的前缀。 在控制器上放置路由属性会使控制器中的所有操作都使用属性路由。
[ApiController]
[Route("products")]
public class ProductsApiController : ControllerBase
{[HttpGet]public IActionResult ListProducts(){return ControllerContext.MyDisplayRouteInfo();}[HttpGet("{id}")]public IActionResult GetProduct(int id){return ControllerContext.MyDisplayRouteInfo(id);}
}
属性路由顺序
路由构建树并同时匹配所有终结点:
- 路由条目的行为就像以理想的顺序排列一样。
- 最具体的路由有机会在更通用的路由之前执行。
例如,blog/search/{topic}
之类的属性路由比 blog/{*article}
之类的属性路由更具体。 默认情况下,blog/search/{topic}
路由具有更高的优先级,因为它更具体。 使用传统路由时,开发人员负责按所需顺序放置路由。
属性路由可以使用 Order 属性配置顺序。 框架提供的所有路由属性都包括 Order
。 路由按 Order
属性的升序进行处理。 默认顺序为 0
。 使用 Order = -1
设置的路由在未设置顺序的路由之前运行。 使用 Order = 1
设置的路由在默认路由顺序之后运行。
路由模板 [controller]、[action]、[area] 中的标记替换
为方便起见,属性路由支持标记替换,方法是将标记用方括号([
、]
)括起来。 标记 [action]
、[area]
和 [controller]
替换为定义了路由的操作中的操作名称值、区域名称值和控制器名称值。
[Route("[controller]/[action]")]
public class Products0Controller : Controller
{[HttpGet] //匹配Products0/Listpublic IActionResult List(){return ControllerContext.MyDisplayRouteInfo();}[HttpGet("{id}")]//匹配 /Products0/Edit/{id}public IActionResult Edit(int id){return ControllerContext.MyDisplayRouteInfo(id);}
}
多个属性路由
属性路由支持定义多个访问同一操作的路由。 此操作最常用于模拟默认传统路由的行为,如以下示例所示:
[Route("Store")]
[Route("[controller]")]
public class Products6Controller : Controller
{[HttpPost("Buy")] // Matches 'Products6/Buy' and 'Store/Buy'[HttpPost("Checkout")] // Matches 'Products6/Checkout' and 'Store/Checkout'public IActionResult Buy(){return ControllerContext.MyDisplayRouteInfo();}
}
指定属性路由的可选参数、默认值和约束
属性路由支持使用与传统路由相同的内联语法,来指定可选参数、默认值和约束。
public class Products14Controller : Controller
{[HttpPost("product14/{id:int}")]public IActionResult ShowProduct(int id){return ControllerContext.MyDisplayRouteInfo(id);}
}
在前面的代码中,[HttpPost("product14/{id:int}")]
应用路由约束。 Products14Controller.ShowProduct
操作仅与 /product14/3
等 URL 路径匹配。 路由模板部分 {id:int}
将该段限制为仅整数。
URL 生成和环境值
应用可以使用路由 URL 生成功能来生成指向操作的 URL 链接。 生成 URL 可消除硬编码URL,使代码更稳定、更易维护。 本部分重点介绍 MVC 提供的 URL 生成功能,并且仅涵盖 URL 生成工作原理的基础知识。
IUrlHelper 接口用于生成 URL,是 MVC 与路由之间的基础结构的基础部分。 在控制器、视图和视图组件中,可通过 Url
属性获得 IUrlHelper
的实例。
在以下示例中,将通过 Controller.Url
属性使用 IUrlHelper
接口来生成指向另一项操作的 URL。
public class UrlGenerationController : Controller
{public IActionResult Source(){// Generates /UrlGeneration/Destinationvar url = Url.Action("Destination");return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");}public IActionResult Destination(){return ControllerContext.MyDisplayRouteInfo();}
}
这里MyDisplayRouteInfo由 Rick.Docs.Samples.RouteInfo NuGet 包提供,会显示路由信息。
如果应用使用的是传统默认路由,则 url
变量的值将为 URL 路径字符串 /UrlGeneration/Destination
。 此 URL 路径由路由通过组合以下内容创建:
- 当前请求的路由值,称为环境值。
- 传递到
Url.Action
的值,并将这些值替换到路由模板中:
ambient values: { controller = "UrlGeneration", action = "Source" } values passed to Url.Action: { controller = "UrlGeneration", action = "Destination" } route template: {controller}/{action}/{id?} result: /UrlGeneration/Destination
路由模板中的每个路由参数都会通过将名称与这些值和环境值匹配,来替换掉原来的值。 没有值的路由参数可以:
- 使用默认值(如果有)。
- 如果可选,则跳过。 例如,路由模板
{controller}/{action}/{id?}
中的id
。
Areas
区域是一项 MVC 功能,用于将相关功能作为一个单独的组组织到一个组中:
- 控制器操作的路由命名空间。
- 视图的文件夹结构。
通过使用区域,应用可以有多个名称相同的控制器,只要它们具有不同的区域。 通过向 controller
和 action
添加另一个路由参数 area
,可使用区域为路由创建层次结构。 本部分讨论路由如何与区域交互。
app.MapAreaControllerRoute("blog_route", "Blog","Manage/{controller}/{action}/{id?}");
app.MapControllerRoute("default_route", "{controller}/{action}/{id?}");
传统路由依赖于顺序。 一般情况下,具有区域的路由应放在路由表中靠前的位置,因为它们比没有区域的路由更具体。
在前面的示例中,路由值 { area = Blog, controller = Users, action = AddUser }
匹配以下操作:
using Microsoft.AspNetCore.Mvc;namespace MyApp.Namespace1
{[Area("Blog")]public class UsersController : Controller{// GET /manage/users/adduserpublic IActionResult AddUser(){var area = ControllerContext.ActionDescriptor.RouteValues["area"];var actionName = ControllerContext.ActionDescriptor.ActionName;var controllerName = ControllerContext.ActionDescriptor.ControllerName;return Content($"area name:{area}" +$" controller:{controllerName} action name: {actionName}");} }
}
[Area] 属性将控制器表示为区域的一部分。 此控制器位于 Blog
区域。 没有属性的[Area]
控制器不是任何区域的成员,并且当路由提供路由值时area
不匹配。
相关文章:
ASP.NET Core中的路由
传统路由 app.MapControllerRoute( name: "default", pattern: "{controllerHome}/{actionIndex}/{id?}"); MapControllerRoute用于创建单个路由。 单个路由命名为 default 路由 。大多数具有控制器和视图的应用都使用类似 default 路由的路由模板。 之所…...

VBA提高篇_26 Textbox多行_ListBox_ComboBox
文章目录1. 文本框多行换行2. ListBox: 列表框2.1 列表框中添加条目的三种方法:3. ComboBox 组合框: 属性方法等同于以上ListBox1. 文本框多行换行 MultiLine: 控制文本框多行自动换行() Enterkeybehevior: True 代表允许在文本框中使用回车键换行 WordWrap: True 代表自动换…...

python环境配置
python环境配置一、ADB环境配置1、ADB下载路径:2、点击下载3、解压并放到本地磁盘4、配置ADB环境变量二、Python环境配置1、Python下载路径:2、点击下载(默认下载最新的)3、解压并放到本地磁盘4、配置Python环境变量5、配置pip环境变量三、Pycharm安装1、pycharm下载路径:2、点…...

集算器连接外部库
1. 配置jar包将以下jar包从报表的类路径(【安装根目录】\report\lib或【安装根目录】\report\web\webapps\demo\WEB-INF\lib)中拷贝到集算器目录(【安装根目录】\esProc\ extlib\mongoCli);润乾外部库核心jar为:scu-mo…...

力扣刷题|216.组合总和 III、17.电话号码的字母组合
文章目录LeetCode 216.组合总和题目链接🔗思路LeetCode 17.电话号码的字母组合题目链接🔗思路LeetCode 216.组合总和 题目链接🔗 LeetCode 216.组合总和 思路 本题就是在[1,2,3,4,5,6,7,8,9]这个集合中找到和为n的k个数的组合。 相对于7…...

机器学习笔记之谱聚类(一)k-Means聚类算法介绍
机器学习笔记之谱聚类——K-Means聚类算法介绍引言回顾:高斯混合模型聚类任务基本介绍距离计算k-Means\text{k-Means}k-Means算法介绍k-Means\text{k-Means}k-Means算法示例k-Means\text{k-Means}k-Means算法与高斯混合模型的关系k-Means\text{k-Means}k-Means算法的…...

云原生周刊 | 2023 年热门:云 IDE、Web Assembly 和 SBOM | 2023-02-20
在 CloudNative SecurityCon 上,云原生计算基金会的首席技术官 Chris Aniszczyk 在 The New Stack Makers 播客的这一集中强调了 2023 年正在形成几个趋势: 随着 GitHub 的 Codespaces 平台通过集成到 GitHub 服务中获得认可,云 IDE…...

python 打包EXE
注: 从个人博客园 移植而来 环境: Windows7 Python 2.7 参考: 使用pyinstaller打包python程序 Pyinstaller 打包发布经验总结 Using PyInstaller 简介 使用python引用第三方的各种模块编写一个工具后,如果想发给其他人&…...

CANopen概念总结、心得体会
NMT网络管理报文: NMT 主机和 NMT 从机之间通讯的报文就称为 NMT 网络管理报文。常见报文说明: 0101---------------网络报文发送Nmt_Start_Node,让电机进入OP模式(此时还不会发送同步信号) setState(d, Operational)------------------开启…...

【2】MYSQL数据的导入与导出
文章目录 MYSQL-库(相同库名称)的导入导出MYSQL-库(不同库名称)的导入导出MYSQL-表的导入导出MYSQL-表的指定查询记录导入导出前提: 客户端工具是:SQLyog MYSQL-库(相同库名称)的导入导出 1、选中指定库——右键,选择【将数据库复制到不同的主机/数据库】 2、选中指…...

Kaggle系列之CIFAR-10图像识别分类(残差网络模型ResNet-18)
CIFAR-10数据集在计算机视觉领域是一个很重要的数据集,很有必要去熟悉它,我们来到Kaggle站点,进入到比赛页面:https://www.kaggle.com/competitions/cifar-10CIFAR-10是8000万小图像数据集的一个子集,由60000张32x32彩…...

ESP-C3入门11. 创建最基本的HTTP请求
ESP-C3入门11. 创建最基本的HTTP请求一、menuconfig配置二、配置 CMakeLists1. 设置项目的额外组件目录2. 设置头文件搜索目录三、在 ESP32 上执行 HTTP 请求的基本步骤1. 创建 TCP 连接2. 设置 HTTP 请求3. 发送 HTTP 请求4. 接收 HTTP 响应5. 处理 HTTP 响应6. 关闭 TCP 连接…...

K8S+Jenkins+Harbor+Docker+gitlab集群部署
K8SJenkinsHarborDockergitlab服务器集群部署 目录K8SJenkinsHarborDockergitlab服务器集群部署1.准备以下服务器2.所有服务器统一处理执行2.1 关闭防火墙2.2 关闭selinux2.3 关闭swap(k8s禁止虚拟内存以提高性能)2.4 更新yum (看需要更新)2.5 时间同步2…...

看见统计——第四章 统计推断:频率学派
看见统计——第四章 统计推断:频率学派 接下来三节的主题是中心极限定理的应用。在不了解随机变量序列 {Xi}\{X_i\}{Xi} 的潜在分布的情况下,对于大样本量,中心极限定理给出了关于样本均值的声明。例如,如果 YYY 是一个 N(0&am…...

2023年2月访问学者博士后热门国家出入境政策变化汇总
近期关于出国的咨询量日益增多,出入境政策也是其中之一。所以本期知识人网小编汇总了最新访问学者和博士后关注的热门国家及地区入境政策变化,提供给大家。目前各国入境政策大致分为三种:一、 无法入境的国家如:摩洛哥、朝鲜等。二…...

“离开浪浪山”是假象,80%年轻人下班后还在学习,真实是想先上个山。
最近,又有一个关于年轻人与职场的新词横空出世—— 浪浪山。 什么是浪浪山? 每个人心中都有一座浪浪山。 浪浪山,其实是人生的一种状态,步入社会时满腔热血,然而很快就被现实给修理了一顿;想要辞职不干出去…...

Kotlin 33. CompileSdkVersion 和 targetSdkVersion 有什么区别?
CompileSdkVersion 和 targetSdkVersion 有什么区别? 在 build.gradle (Module) 文件中,我们通常会看到 CompileSdkVersion 和 targetSdkVersion 的使用,比如下面是一个完整的 build.gradle (Module) 文件: plugins {id com.and…...

实用调试技巧——“C”
各位CSDN的uu们你们好呀,今天小雅兰的内容是实用调试技巧,其实小雅兰一开始,也不知道调试到底是什么,一遇到问题,首先就是观察程序,改改这里改改那里,最后导致bug越修越多,或者是问别…...

JavaScript - 函数
文章目录一、箭头函数二、函数名三、理解参数3.1 箭头函数中的参数四、没有重载五、默认参数值5.1 默认参数作用域与暂时性死区六、参数扩展与收集6.1 扩展参数6.2 收集参数七、函数声明与函数表达式八、函数作为值九、函数内部9.1 arguments9.2 this9.3 caller9.4 new.target十…...

Cesium 卫星轨迹、卫星通信、卫星过境,模拟数据传输。
起因:看了cesium官网卫星通信示例发现只有cmzl版本的,决定自己动手写一个。欢迎大家一起探讨,评论留言。 效果 全部代码在最后 起步 寻找卫星轨迹数据,在网站space-track上找的,自己注册账号QQ邮箱即可。 卫星轨道类…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟
2025年4月29日,在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上,可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞,强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...
LangChain【6】之输出解析器:结构化LLM响应的关键工具
文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器?1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...