ASP.NET Core 2.2 : 扒一扒新的Endpoint路由方案

2023-11-06 13:48

本文主要是介绍ASP.NET Core 2.2 : 扒一扒新的Endpoint路由方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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两个中间件处理,下面依旧通过一幅图来详细看一下:

 二、流程及解析

640?wx_fmt=png

                                                                            图一

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

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

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

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

640?wx_fmt=png

② 第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,而通过这个方法的代码可以看出它只是在第一次请求的时候执行一次。

640?wx_fmt=png

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

640?wx_fmt=png

                                                      图二

具体代码如下:

640?wx_fmt=png

640?wx_fmt=png

本质就是计算出一个个可能被请求的请求终结点,也就是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

640?wx_fmt=jpeg


这篇关于ASP.NET Core 2.2 : 扒一扒新的Endpoint路由方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/356993

相关文章

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

SpringBoot3.X 整合 MinIO 存储原生方案

《SpringBoot3.X整合MinIO存储原生方案》本文详细介绍了SpringBoot3.X整合MinIO的原生方案,从环境搭建到核心功能实现,涵盖了文件上传、下载、删除等常用操作,并补充了... 目录SpringBoot3.X整合MinIO存储原生方案:从环境搭建到实战开发一、前言:为什么选择MinI

Knife4j+Axios+Redis前后端分离架构下的 API 管理与会话方案(最新推荐)

《Knife4j+Axios+Redis前后端分离架构下的API管理与会话方案(最新推荐)》本文主要介绍了Swagger与Knife4j的配置要点、前后端对接方法以及分布式Session实现原理,... 目录一、Swagger 与 Knife4j 的深度理解及配置要点Knife4j 配置关键要点1.Spri

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

Springboot3+将ID转为JSON字符串的详细配置方案

《Springboot3+将ID转为JSON字符串的详细配置方案》:本文主要介绍纯后端实现Long/BigIntegerID转为JSON字符串的详细配置方案,s基于SpringBoot3+和Spr... 目录1. 添加依赖2. 全局 Jackson 配置3. 精准控制(可选)4. OpenAPI (Spri

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

在Java中将XLS转换为XLSX的实现方案

《在Java中将XLS转换为XLSX的实现方案》在本文中,我们将探讨传统ExcelXLS格式与现代XLSX格式的结构差异,并为Java开发者提供转换方案,通过了解底层原理、性能优势及实用工具,您将掌握... 目录为什么升级XLS到XLSX值得投入?实际转换过程解析推荐技术方案对比Apache POI实现编程