ASP.NET Core MVC中app.UseMvc()与app.UseEndpoints()配置路由有什么区别?
ASP.NET Core 中
UseMvc 与端点路由(UseRouting+UseEndpoints)的区别及运行原理 核心区别
- 适配范围不同:
UseMvc是ASP.NET Core 2.x及更早版本专属的MVC路由方案,仅支持MVC控制器/Action的路由处理;3.x开始推出的端点路由体系是全框架通用的路由方案,除MVC外还同时支持Razor Pages、SignalR、gRPC、健康检查、自定义端点等所有类型的服务路由。 - 中间件灵活性不同:
UseMvc是单中间件封装,路由匹配和端点执行逻辑全部耦合在同一个中间件内部,授权、CORS等逻辑要么全局放在UseMvc之前生效,要么写为MVC过滤器,无法针对单个路由做中间件级别的定制;端点路由拆分为UseRouting(路由匹配)、中间件执行、UseEndpoints(端点执行)三个阶段,你可以在路由匹配完成后、端点执行前插入任意自定义中间件,直接基于已经匹配到的端点信息做逻辑处理,不需要额外做路径解析。 - 配置方式不同:
UseMvc的路由注册统一在UseMvc的委托参数中完成,示例:
端点路由的不同类型服务路由可以分开注册,MVC路由注册示例:app.UseMvc(routes => { routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}"); });app.UseEndpoints(endpoints => { endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); // 可以同时注册其他类型端点 endpoints.MapHub<ChatHub>("/chat"); endpoints.MapHealthChecks("/health"); }); - 3.x+兼容逻辑:ASP.NET Core 3.x+版本中
UseMvc已经被标记为过时,此时调用UseMvc本质是兼容层封装,内部会自动注册三个端点路由中间件,执行逻辑和显式写三个中间件一致,但会丧失在路由匹配后插入自定义中间件的能力。
各自内部运行原理
UseMvc(2.x原生版本)的运行原理
- 请求进入
UseMvc中间件后,内部会遍历所有预注册的MVC路由模板,逐个匹配当前请求的路径、请求方法等信息。 - 匹配成功则解析出controller、action、路由参数等信息,直接触发MVC管道执行:包含过滤器管道执行、控制器实例化、Action执行、结果返回,执行完成后直接终止中间件管道,不会往后传递请求。
- 匹配失败则直接将请求传递给后续中间件,不做任何处理。
原生
UseMvc的路由匹配结果仅在中间件内部可见,后续中间件无法获取路由匹配信息。
端点路由体系(UseRouting+UseEndpoints)的运行原理
端点路由将路由处理拆分为三个独立阶段,所有阶段都基于全局的端点元数据运行:
UseRouting执行阶段:仅完成路由匹配逻辑,遍历应用所有注册的端点,匹配到对应端点后将端点对象、路由参数全部存储到HttpContext.Endpoint属性中,不执行业务逻辑。匹配失败的话HttpContext.Endpoint会被设为null,请求继续往后传递。- 中间件处理阶段(
UseRouting和UseEndpoints之间):所有这个位置的中间件都可以直接读取HttpContext.Endpoint中的匹配结果,比如UseAuthorization会直接读取端点上绑定的[Authorize]特性做权限校验,不需要自己解析路由找对应控制器的特性,校验失败直接返回错误,不会走到后续执行阶段。 UseEndpoints执行阶段:读取HttpContext.Endpoint中的匹配结果,如果存在合法端点就触发端点绑定的执行委托,MVC类型端点就会触发MVC管道执行对应Action,其他类型端点执行对应逻辑;如果没有匹配到端点,就将请求传递给后续中间件。
内容的提问来源于stack exchange,提问作者Pulkit Sharma
相关产品推荐
相关产品推荐

