ASP.NET|ASP.NET Core中MVC模式实现路由一
目录
- 1.前言
- 2.设置路由中间件
- 3.传统路由
- 4.多个路由
- 4.1定义多个路由
- 4.2区分操作
- 5.属性路由
- 5.1 属性路由
- 5.2 使用 Http[Verb] 属性的属性路由
- 5.3合并路由
- 5.4指定属性路由的可选参数、默认值和约束
- 5.4自定义属性路由
ASP.NET Core中MVC模式实现路由一
ASP.NET Core中MVC模式实现路由二
1.前言 ASP.NET Core MVC使用路由中间件来匹配传入请求的URL并将它们映射到操作(Action方法)。路由在启动代码(Startup.Configure方法)或属性(Controller Action属性)中定义。路由描述应如何将URL路径与操作(Action方法)相匹配。它还用于在响应中生成送出的URL。
路由操作可以设置中间件,支持传统路由、属性理由(通过在Controller Action上放置理由可实现)、多个路由。
2.设置路由中间件 在Configure方法中,可能会看到与下面类似的设置路由中间件代码:
app.UseMvc(routes =>{routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
等价于
//默认模版就是 "{controller=Home}/{action=Index}/{id?}"app.UseMvcWithDefaultRoute();
在UseMvc的匿名方法中,MapRoute表示创建单个路由,指定为默认(default)路由、路由模版“{controller=Home}/{action=Index}/{id?}”。
路由模版“{controller=Home}/{action=Index}/{id?}”的意思是可以匹配“/Home/Index/5”的URL路径。也就是说:
- {controller=Home}将Home定义为默认controller。
- {action=Index}将Index定义为默认action。
- {id?}将id定义为可选参数。
3.传统路由 默认路由:
routes.MapRoute(name: "default", template: "{controller=Home}/{action=Index}/{id?}");
上述代码就是一个传统路由,将这种方式称为传统路由的原因在于,它为URL路径设立了一个约定:
- 第一个路径段映射到控制器名称
- 第二段映射到操作名称。
- 第三段用于可选id(用于映射到模型实体)。
4.多个路由
4.1定义多个路由
通过对UseMvc匿名方法添加多个路由,这样做可以定义多个约定或添加专用于特定操作的传统路由,比如:
app.UseMvc(routes =>{//第一个路由routes.MapRoute("blog", "blog/{*article}",defaults: new { controller = "Blog", action = "Article" }); //第二个路由routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); });
第一个路由里{*article}是表示使用catch-all路由参数来捕获URL路径的剩余部分。下面我们通过测试来验证下:
文章图片
●"blog/{*article}":
文章图片
●"blog/{article}":
文章图片
通过上述测试可以知道,加星号的路由在传参字符串中加了斜杠依然能够打开,没加星号的路由在传参字符串中加了斜杠就不能打开了。还有一点要注意的是controller.action接收参数必须跟*后面参数名称一致,不然会接收不到参数值。
4.2区分操作
当controller存在两个action名称一致的方法,MVC必须要进行区分,不然会引发异常,例如:
public class BlogController : Controller{public IActionResult Edit(int id) {}[HttpPost]public IActionResult Edit(int id, Blog blog) {}}
当请求为HTTP POST时MVC会选择Edit(int, Blog),在Http属性为任何其他内容时选择 Edit(int)。如果匹配多个路由,而MVC找不到“最佳”路由Action时,则会引发 AmbiguousActionException异常。
5.属性路由
5.1 属性路由
属性路由使用一组属性将操作(Action)直接映射到路由模板。 在下面的示例中,Configure 方法使用app.UseMvc(),不传递任何路由。HomeController将匹配一组URL,这组URL与默认路由{controller=Home}/{action=Index}/{id?}匹配的URL类似:
public class HomeController : Controller{[Route("")][Route("Home")][Route("Home/Index")]public IActionResult Index(){return View(); }}
下面我们通过表格来看看每个属性路由在浏览器上打开链接是怎样的效果。
Route Template |
Browser |
Page |
Route("") |
[SERVICE_NAME] |
[SERVICE_NAME]/Home/Index |
Route("Home") |
[SERVICE_NAME]/Home |
|
Route("Home/Index") |
[SERVICE_NAME]/Home/Index |
[Route("1")][Route("Home1")][Route("Home1/Index1")]
上述模版名称更改了,但是在浏览器呈现页面还是指向/Home/Index的,也就是说,无论属性路由模版名称如何更改总能打开对应/Home/Index页面。
5.2 使用 Http[Verb] 属性的属性路由
属性路由还可以使用Http[Verb]属性,比如HttpPostAttribute。所有这些属性都可采用路由模板。此示例展示与同一路由模板匹配的两项操作:
public class BlogController : Controller{[HttpGet("/article/{id}", Name = "Article_List")]public IActionResult Article(string id){return View(); }}
当我们在浏览器上输入[SERVICE_NAME]/article/1时候,通过DEBUG我们可以看到响应结果:
文章图片
通过响应结果可以知道属性路由首先将URL与路由属性定义的路由模板集([HttpGet("/article/{id}", Name = "Article_List")])进行匹配。一旦某个路由模板匹配,就会应用IActionConstraint约束来确定可以执行的操作。
5.3合并路由
根据业务场景如果我们需要将某个Controller重新命名为以便访问该Controller下面所有action,那么该如何设置呢?下面通过示例来演示下:
[Route("homes")]public class HomeController : Controller{[HttpGet("{id}")]public IActionResult Index(){return View(); }}
根据上述代码,在HomeController上放置路由属性([Route("homes")])会使控制器中的所有操作(Action)都使用该属性路由。也就是说只有URL HTTPGet :[SERVICE_NAME]/homes/1才能访问Index视图。这种做法好处是,HomeController下的每个Action操作不用单独添加Route("homes")属性,只需要在HomeController外放置一个全局Route("homes")属性即可应用到每个Action去,减少路由属性重复。
5.4指定属性路由的可选参数、默认值和约束
属性路由同时也支持使用与传统路由相同的内联语法,来指定可选参数、默认值和约束。下面请看示例:
public class HomeController : Controller{[HttpGet("homes/{id:int}")]public IActionResult Index(int id){return View(); }}
上述代码执行结果我们通过表格来看看效果:
Browser |
Result status |
[SERVICE_NAME]/homes/1 |
200 |
[SERVICE_NAME]/homes/qwe |
404 |
5.4自定义属性路由
我们可以通过框架自带的IRouteTemplateProvider接口自定义路由属性(例如类似[HttpGet]、[Route("homes")]等属性)。当应用程序启动时,MVC会查找控制器类和操作方法上的属性,并使用实现IRouteTemplateProvider的属性生成一组初始路由。此部分通过一个简单的示例说明了如何使用应用程序自定义属性路由:
public class MyControllerAttribute : Attribute, IRouteTemplateProvider{//实现接口的三个属性,这里的[controller]是一个标记替换。public string Template => "api/[controller]/{action}/{id?}"; public int? Order { get; set; }public string Name { get; set; }}
新建一个路由属性类自定义属性路径,然后在Controller或者Action上放置自定义属性路由。
public class BlogController : Controller{[MyController()]public IActionResult Article(string id){return View(); }}
通过执行[SERVICE_NAME]/api/Blog/Article/1链接时访问成功,也就是说自定义属性路由成功。
【ASP.NET|ASP.NET Core中MVC模式实现路由一】到此这篇关于ASP.NET Core中MVC模式实现路由的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
推荐阅读
- React中的renderProps和childrenProps
- pytorch|yolov5-gpu版本部署与测试中遇到的问题与解决
- 20220406Java字符串操作类中scompareTo()
- 如何在|如何在 Java 中实现最小生成树算法
- python|关于举办“2022年(第15届)中国大学生计算机设计大赛”通知
- java|2020 中国大学生计算机设计大赛
- Git 中的算法-最近公共祖先
- Java中ArrayList的使用详细介绍
- 云栖号技术分享|专访李飞飞 (从清华附中高材生到阿里飞刀,一口井钻出「云原生」)
- Vue3|Vue3 + Echarts 5 绘制带有立体感流线中国地图,建议收藏