如何在 ASP.NET Core 中使用 Route 特性
ASP.NET Core 中的 Route 中间件的职责在于将 request 匹配到各自 Route 处理程序上,Route 分两种:基于约定
和 基本特性
模式。
基于约定
模式的Route采用集中化的方式,而 基于特性
的方式允许你在 Action 或者 Controller 上单独定义,到底采用哪一种可以基于你自己的应用场景,本篇就来讨论如何使用 基于特性
模式。
创建 Controller 类
创建一个 DefaultController 类,新增如下代码。
public class DefaultController : Controller{[Route("")][Route("Default")][Route("Default/Index")]public ActionResult Index(){return new EmptyResult();}[Route("Default/GetRecordsById/{id}")]public ActionResult GetRecordsById(int id){string str = string.Format("The id passed as parameter is: {0}", id);return Ok(str);}}
Controller 级别定义 Route 特性
Route特性可用于 Controller 和 Action 级别,值得注意的是,如果应到到前者,那么 Controller 下的所有 Action 都受这个 Route 管控。
如果你仔细观察上面的 DefaultController 类代码,你会发现两个 Action 方法的 Route 路径都有 Default
前缀,这就不优雅了,优化方式就是把 Route
路径中的 Default 提取到 Controller 级别,代码如下:
[Route("Default")]
public class DefaultController : Controller
{[Route("")][Route("Index")]public ActionResult Index(){return new EmptyResult();}[HttpGet][Route("GetRecordsById/{id}")]public ActionResult GetRecordsById(int id){string str = string.Format("The id passed as parameter is: {0}", id);return Ok(str);}
}
可以看出当 Controller 和 Action 级别都被 Route 打上标记之后,Asp.Net Core 中的 Route 引擎会自动将两者拼接起来,当然更简单粗暴的做法就是在 Controller 上使用 RoutePrefix
特性,如下代码所示:
[RoutePrefix("services")]
public class HomeController : Controller
{//Action methods
}
Action 级别定义 Route 特性
参考刚才的 DefaultController 类,我在 Index 方法上面定义了三个 Route 特性,这就意味着下面三种 Route
都可以访问到 Index()
方法,如下代码所示:
http://localhost:11277
http://localhost:11277/home
http://localhost:11277/home/index
常常在 基于约定
模式的Route中,它的 Route template
会有一些对参数的约定,比如下面的代码:
app.UseEndpoints(endpoints =>{endpoints.MapControllerRoute(name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");});
同样 基于特性
模式的 Route 也是可以使用参数模式的,比如文章之前的 DefaultController.GetRecordsById
就是的,值得注意的是模板中的 {id}
表示可接收任何参数,如 string,int 等等,如果你想限定为 int 的话,也是可以实现的。
使用 Route 约束
Route 约束
就是 Controller 前的一个防火墙,他会踢掉一些不合规范的 Action 请求,比如说:你要求某个 Action 接收的参数必须是 int,那在 Route 模板中定义的语法格式一定是这样的 {parameter:constraint}
,如下代码所示:
[Route("Default/GetRecordsById/{id:int}")]
public ActionResult GetRecordsById(int id)
{string str = string.Format("The id passed as parameter is: {0}", id);return Ok(str);
}
在 Route 中使用可选参数
你也可以在 Route Template 上指定可选参数,意味着这个参数可传可不传,格式如下:
[Route("Sales/GetSalesByRegionId/{id?}")]
有一点非常重要,当你使用了 Route特性 之后,其实 Controller 或者 Action 的名字就不再重要了,因为 Route处理引擎 已经不再将其作为参考选项,下面的代码片段展示了如何在 Action 方法上变更 Route template 格式。
[Route("Home/GetRecordsById/{id:int}")]
public ActionResult GetRecordsById(int id)
{string str = string.Format("The id passed as parameter is: {0}", id);return Ok(str);
}
接下来可以直接使用如下地址访问 GetRecordsById 方法。
http://localhost:11277/home/GetRecordsById/1
对 Action 中的参数使用多个约束
真实场景中你不仅要求 id 必须是整数,还要求必须有一定意义,比如说最小值为1,对这种有 多重约束
的需求如何去实现呢?请看下面代码。
[Route("Default/GetRecordsById/{id:int:min(1)}")]
public ActionResult GetRecordsById(int id)
{string str = string.Format("The id passed as parameter is: {0}", id);return Ok(str);
}
常使用的 Route 约束
int 限定为 int 类型
max/min 限定 int 的最大数和最小数
minlength 限定 string 的最小长度
regex 限定符合的正则
创建自定义的 Route 约束
如果上面的一些约束不满足你的要求,你完全可以为你的场景深度定制,做法就是使用 IRouteConstraint 接口并实现它的 Match 方法即可,如下代码所示:
public class CustomRouteConstraint : IRouteConstraint{public bool Match(HttpContext httpContext, IRouter route,string routeKey,RouteValueDictionary values, RouteDirection routeDirection){throw new NotImplementedException();}}
在 Controller 上使用 token 占位符
所谓的 token 占位符
就是具有一些特定含义的占位符号,比如说:[action], [area] 和 [controller]
,分别表示用你真实的 Controller 和 Action 去替换,下面的代码展示了如何使用这种模式去实现。
[Route("[controller]/[action]")]
public class HomeController : Controller
{private readonly ILogger<HomeController> _logger;public HomeController(ILogger<HomeController> logger){_logger = logger;}public IActionResult Index(){return View();}//Other action methods
}
整体来看,基于特性
的 Route 给了你更多的操控权限,灵活的 Route Template 配置实现了 Controller 和 Action 的解耦,当然这里也不是说 基于约定
的Route 不好,毕竟人家是 Global 级别的,真实场景下两者更多的是混着用。
译文链接:https://www.infoworld.com/article/3569369/how-to-use-attribute-routing-in-aspnet-core.html
如何在 ASP.NET Core 中使用 Route 特性相关推荐
- 如何在 ASP.NET Core 中使用 HttpClientFactory ?
ASP.Net Core 是一个开源的,跨平台的,轻量级模块化框架,可用它来构建高性能的Web程序,这篇文章我们将会讨论如何在 ASP.Net Core 中使用 HttpClientFactory. ...
- 如何在 ASP.Net Core 中使用 Autofac
依赖注入可以有效的实现对象之间的 松耦合 并能够实现代码的可测试和可维护性,ASP.Net Core 提供了一个极简版的容器实现对 依赖注入 的原生支持,然而内置的依赖注入容器相比成熟的 依赖注入容器 ...
- 如何在 ASP.Net Core 中使用 MediatR
MediatR 是一个 中介者模式 的.NET开源实现, 中介者模式 管控了一组对象之间的相互通讯并有效的减少了对象之间错综复杂的相互依赖,在 中介者模式 中,一个对象不需要直接和另一个对象进行通讯, ...
- 如何在ASP.NET Core中使用Azure Service Bus Queue
原文:USING AZURE SERVICE BUS QUEUES WITH ASP.NET CORE SERVICES 作者:damienbod[1] 译文:如何在ASP.NET Core中使用Az ...
- 如何在 ASP.Net Core 中使用 Lamar
ASP.Net Core 自带了一个极简的 开箱即用 的依赖注入容器,实际上,你还可以使用第三方的 依赖注入容器 来替代它,依赖注入是一种设计模式,它能够有效的实现对象之间的解耦并有利于提高单元测试和 ...
- 如何在 ASP.Net Core 中对接 WCF
在 REST API 出现之前,SOAP (Simple Object Access Protocol) 一直都是基于 web 的标准协议,虽然现在 REST 大行其道,但在平时开发中总会遇到对接第三 ...
- 如何在 ASP.Net Core 中使用 NCache
虽然 ASP.Net Core 中缺少 Cache 对象,但它引入了三种不同的cache方式. 内存缓存 分布式缓存 Response缓存 Alachisoft 公司提供了一个开源项目 NCache, ...
- 如何在 ASP.Net Core 中使用 Configuration Provider
ASP.NET Core 是一个开源的,跨平台的,精简的模块化框架,可用于构建高性能,可扩展的web应用程序, ASP.NET Core 中的数据配置常用 k-v 的形式存储,值得注意的是,新的数据配 ...
- 如何在 ASP.Net Core 中使用 Serilog
记录日志的一个作用就是方便对应用程序进行跟踪和排错调查,在实际应用上都是引入 日志框架,但如果你的 日志文件 包含非结构化的数据,那么查询起来将是一个噩梦,所以需要在记录日志的时候采用结构化方式. 将 ...
最新文章
- -%3e运算符在c语言中的作用,C语言逻辑运算符知识整理
- 浅谈JavaScript中的事件
- 推荐一套高效的码字工具
- 软件测试用例_软件测试用例设计实战场景法
- 内网中入侵linux系统,MSSQL 入侵提权之内网渗透案例分析
- 高并发高可用的 架构实践
- Facebook想用机器人取代App
- opencv之求轮廓的凸包
- Joyoshare UltFix快速修复iPhone黑屏死机的问题
- 没想到,这么简单的线程池用法,深藏这么多坑!
- 反思:前一段时间的开发中,忽略了对象概念
- ps色彩范围调暗图片局部
- Cesium加载建筑物模型(shp转Geojson\3Dtiles)
- 分享Python采集的77个PHP整站程序源码
- 【Busybox】Busybox源码分析-04 | ash和login程序
- 分布式多级服务器架构设计构思
- maya导入abc动画_(送给纠结自学3d建模的同学)自学maya,zbrush,substance一个月的感想...
- 响铃:迎风而起的布料B2B平台,谁才是决定生死的命脉?
- Http简介(关于HTTP请求GET和POST的区别)
- python 携程航班信息查询