ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不大,但从内部运行方式上来说,差别还是很大的。上一篇ASP.NET Core;图解路由(2.1 earler)详细介绍了原版路由方案的运行机制,本文仍然通过一幅图来了解一下新版的运行机制,最后再总结一下二者的异同点。

一、概述

此方案从2.2版本开始,被称作终结点路由(下文以“新版”称呼),它是默认开启的,若想采用原来的方案(<=2.1,下文以原版称呼),可以在AddMvc的时候进行设置

services.AddMvc(option=>option.EnableEndpointRouting = false).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

EnableEndpointRouting 默认为true,也就是启用新的Endpoint方案,设置为false则采用旧版(<=2.1)的路由方案。

在配置方法上来说,系统仍然采用在Startup中的use.Mvc()中配置,而实际上内部的处理中间件已由原来的RouterMiddleware改为EndpointMiddleware和EndpointRoutingMiddleware两个中间件处理,下面依旧通过一幅图来详细看一下:

二、流程及解析

图一

为了方便查看,依然对几个“重点对象”做了颜色标识(点击图片可以看大图):

      1. 路由的初始化配置(图的前两个泳道) 

  1. ①  一切依然是从Startup开始,而且和旧版一样,是通过UseMvc方法进行配置,传入routes.MapRoute(...)这样的一个或多个配置, 不做赘述。

  1. 下面着重说一下后面的流程,看一下MvcApplicationBuilderExtensions中的UseMvc方法:

② 第6行,这里会获取并判断设置的EnableEndpointRouting的值,若为false,则采用旧版路由,详见上一篇文章;该值默认为true,即采用新版路由。
 ③ 对应第9行,MvcEndpointDataSource在新版路由中是个非常非常重要的角色,在启动初始化阶段,它完成了路由表存储和转换,此处先用颜色重点标记一下,大家记住它,在后面的流程中详细介绍。
 ④ 对应第16行,同旧版的RouteBuilder一样,这里会new一个 endpointRouteBuilder,二者都是一个IRouteBuilder,所以也同样调用configureRoutes(endpointRouteBuilder)方法(也就是startup中的配置)获取了一个Route的集合(IList<IRouter>)赋值给endpointRouteBuilder.Routes,这里有个特别该注意的地方if (router is Route route && router.GetType() == typeof(Route)) ,也就是这里只接受route类型,终结点路由系统不支持基于 IRouter的可扩展性,包括从 Route继承。
⑤ 对应第20行,这里对刚获取到的endpointRouteBuilder.Routes进行遍历,转换成了一个MvcEndpointInfo的集和,赋值给mvcEndpointDataSource.ConventionalEndpointInfos。
⑥ 之后就是向管道塞中间件了,这里的处理中间件由原来的RouterMiddleware改为EndpointMiddleware和EndpointRoutingMiddleware。

  2.请求的处理(图的后两个泳道)

请求的处理大部分功能在中间件EndpointRoutingMiddleware,他有个重要的属性_endpointDataSource保存了上文中初始化阶段生成的MvcEndpointDataSource,而中间件EndpointMiddleware的功能比较简单,主要是在EndpointRoutingMiddleware筛选出endpoint之后,调用该endpoint的endpoint.RequestDelegate(httpContext)进行请求处理。
 ⑦ InitializeAsync()方法主要是用于调用InitializeCoreAsync()创建一个matcher,而通过这个方法的代码可以看出它只是在第一次请求的时候执行一次。

⑧ MvcEndpointDataSource一个重要的方法UpdateEndpoints(),作用是读取所有action,并将这个action列表与它的ConventionalEndpointInfos列表(见⑤)进行匹配,最终生成一个新的列表。如下图,我们默认情况下只配置了一个"{controller=Home}/{action=Index}/{id?}"这样的路由,默认的HomeController有三个action,添加了一个名为FlyLoloController的controller并添加了一个带属性路由的action,最终生成了7个Endpoint,这有点像路由与action的“乘积”。当然,这里只是用默认程序举了个简单的例子,实际项目中可能会有更多的路由模板注册、会有更多的Controller和Action以及属性路由等。

图二

具体代码如下:

本质就是计算出一个个可能被请求的请求终结点,也就是Endpoint。由此可见,如上一篇文章那样想自定义一个handler来处理特殊模板的方式(如 routes.MapRoute("flylolo/{code}/{name}", MyRouteHandler.Handler);)将被忽略掉,因其无法生成 Endpoint,且此种方式完全可以自定义一个中间件来实现,没必要混在路由中。

⑨ 就是用上面生成的Matcher,携带Endpoint列表与请求URL做匹配,并将匹配到的Endpoint赋值给feature.Endpoint。
            ⑩ 获取feature.Endpoint,若存在则调用其RequestDelegate处理请求httpContext。

三、新版与旧版的异同点总结

简要从应用系统启动和请求处理两个阶段对比说一下两个版本的区别:

1.启动阶段:

这个阶段大部分都差不多,都是通过Startup的app.UseMvc()方法配置一个路由表,一个Route的集合Routes(IList<IRouter>),然后将其简单转换一下

<=2.1:  将Routes转换为RouteCollection

2.2+ :   将Routes转换为List<MvcEndpointInfo>

二者区别不大,虽然名字不同,但本质上还是差不多,都仍可理解为Route的集合的包装。

2.请求处理阶段:

<=2.1:   1. 将请求的URL与RouteCollection中记录的路由模板进行匹配。

2. 找到匹配的Route之后,再根据这个请求的URL判断是否存在对应的Controlled和Action。

3. 若以上均通过,则调用Route的Handler对HttpContext进行处理。

2.2+ :   1. 第一次处理请求时,首先根据启动阶段所配置的路由集合List<MvcEndpointInfo>和_actions.ActionDescriptors.Items(所有的action的信息)做匹配,生成一个列表,这个列表存储了所有可能被匹配的URL模板,如图二,这个列表同样是List<MvcEndpointInfo>,记录了所有可能的URL模式,实际上是列出了一个个可以被访问的详细地址,已经算是最终地址了,即终结点,或许就是为什么叫Endpoint路由的原因。

2.请求的Url和这个生成的表做匹配,找到对应的MvcEndpointInfo。

3. 调用被匹配的MvcEndpointInfo的RequestDelegate方法对请求进行处理。

二者区别就是对于_actions.ActionDescriptors.Items(所有的action的信息)的匹配上,原版是先根据路由模板匹配后,再根据ActionDescriptors判断是否存在对应的Controller和action,而新版是先利用了action信息与路由模板匹配,然后再用请求的URL进行匹配,由于这样的工作只在第一次请求的时候执行,所以虽然没有做执行效率上的测试,但感觉应该是比之前快的。

原文链接:https://www.cnblogs.com/FlyLolo/p/ASPNETCore2_16.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

ASP.NET Core 2.2 : 扒一扒新的Endpoint路由方案相关推荐

  1. ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案(转)

    ASP.NET Core 系列目录 ASP.NET Core 从2.2版本开始,采用了一个新的名为Endpoint的路由方案,与原来的方案在使用上差别不大,但从内部运行方式上来说,差别还是很大的.上一 ...

  2. ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案

    ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案 原文:ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案 ASP.NET Core 从2.2版本开始 ...

  3. ASP.NET Core 源码阅读笔记(5) ---Microsoft.AspNetCore.Routing路由

    这篇随笔讲讲路由功能,主要内容在项目Microsoft.AspNetCore.Routing中,可以在GitHub上找到,Routing项目地址. 路由功能是大家都很熟悉的功能,使用起来也十分简单,从 ...

  4. Do You Kown Asp.Net Core -- Asp.Net Core 2.0 未来web开发新趋势 Razor Page

    Razor Page介绍 前言 上周期待已久的Asp.Net Core 2.0提前发布了,一下子Net圈热闹了起来,2.0带来了很多新的特性和新的功能,其中Razor Page引起我的关注,作为web ...

  5. asp.net core 启动报错 Unable to configure HTTPS endpoint. No server certificate was specified

    开发环境 windows 10 visual studio 2019 版本 16.8.6 .net sdk 版本 5.0.103 问题复盘 使用 visual studio 2019 创建了一个全新的 ...

  6. ASP.NET Core 2.2中的Endpoint路由

    Endpoint路由 在ASP.NET Core 2.2中,新增了一种路由,叫做Endpoint(终结点)路由.本文将以往的路由系统称为传统路由. 本文通过源码的方式介绍传统路由和Endpoint路由 ...

  7. ASP.NET Core配置环境变量和启动设置

    在这一部分内容中,我们来讨论ASP.NET Core中的一个新功能:环境变量和启动设置,它将开发过程中的调试和测试变的更加简单.我们只需要简单的修改配置文件,就可以实现开发.预演.生产环境的切换. A ...

  8. ASP.NET Core MVC/WebAPi如何构建路由?

    前言 本节我们来讲讲ASP.NET Core中的路由,在讲路由之前我们首先回顾下之前所讲在ASP.NET Core中的模型绑定这其中有一个问题是我在项目当中遇见的,我们下面首先来看看这个问题. 回顾A ...

  9. ASP.NET Core 1.1 Preview 1 简介(包含.NETCore 1.1升级公告)

    ASP.NET Core 1.1 Preview 1于2016年10月25日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强. 要将现有项目更新到ASP.NET Core 1.1 Pre ...

最新文章

  1. 安装VMware Workstation提示the msi failed的解决办法
  2. linux驱动常用函数
  3. jenkins_使用Jenkins / Hudson远程API检查作业状态
  4. C2872 “ACCESS_MASK”: 不明确的符号
  5. [WF4.0]工作流设计器Rehosting(一)
  6. js字符串函数 [http://www.cnblogs.com/qfb620/archive/2011/07/28/2119799.html]
  7. strong、copy和mutableCopy详解
  8. Hive的HQL(2)
  9. 51nod 1268 和为K的组合 dfs
  10. Linux:Vim的安装与配置
  11. Android Studio 2.3报错: Error:Cause: buildToolsVersion is not specified解决
  12. drbd mysql mha_浅谈秒级故障切换!用MHA轻松实现MySQL高可用(三)
  13. php apk 分包,H5打包出APP,分包
  14. 大数据之clickhouse各类引擎
  15. 霍夫斯特拉大学计算机科学专业排名,霍夫斯特拉大学专业排名一览(含历年专业排名信息,USNEWS美国大学排名版)...
  16. 一万年太久,只争朝夕_散文网
  17. clappr:可扩展网页媒体播放器使用(在vue中的使用)
  18. chrome 查看日志
  19. 企业如何用InfBox架设自己的内部即时信息IM服务器
  20. Synergy 使用

热门文章

  1. 50多种在Photoshop中删除图像背景的工具和技术,第3页
  2. 汇新杯┃拼多多黄峥:普通的创业者,不普通的朋友圈_创成汇
  3. webform 页面传值的方法总结
  4. MDT部署中命令行脚本的使用。
  5. 2021,我的输入输出
  6. 6张图,带你深入理解GitOps,真硬核!
  7. 华为云服务器初探二(完结)
  8. 如何摆脱「自我否定」状态
  9. Blazor 路由及导航开发指南
  10. 测试龙芯 LoongArch .NET之 使用 FastTunnel 做内网穿透远程计算机