ASP.NET Core的路由[4]:来认识一下实现路由的RouterMiddleware中间件

本文涉及的产品
云原生网关 MSE Higress,422元/月
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
任务调度 XXL-JOB 版免费试用,400 元额度,开发版规格
简介:

虽然ASP.NET Core应用的路由是通过RouterMiddleware这个中间件来完成的,但是具体的路由解析功能都落在指定的Router对象上,不过我们依然有必要以代码实现的角度来介绍一下这个中间件。在这之前,我们先来认识一个特殊的特性。[本文已经同步到《ASP.NET Core框架揭秘》之中]

让RouterMiddleware中间件委托Router完整整个路由工作之后,解析出来的路由参数会以一个RouteData对象的形式存储在RouteContext上下文中。但是RouteContext是为Router的执行建立的上下文,路由解析工作完成之后,这个上下文的生命周期也随着结束,既然整个RouteContext上下文都不存在了,请求处理的后续步骤如何获取这个RouteData对象呢?

通过《注册URL模式与HttpHandler的映射关系》的实例演示我们知道可以调用HttpContext的扩展方法GetRouteData来获取这个包含素所有路由参数的RouteData对象,这个意味着原本依附于RouteContext上下文的RouteData最终会被附加到代表当前请求上下文的HttpContext上,而具体承载这个RouteData的就是这个名为RoutingFeature的特性。RoutingFeature是我们对所有实现了IRoutingFeature接口的所有类型以及对应对象的统称。如下面的代码片段所示,这个接口通过属性RouteData来保存最终附加到HttpContext的RouteData。RoutingFeature类是这个接口的默认实现者,我们的RouterMiddleware默认情况下就是使用这个对象。

   1: public interface IRoutingFeature
   2: {
   3:     RouteData RouteData { get; set; }
   4: }
   5:  
   6: public class RoutingFeature : IRoutingFeature
   7: {
   8:     public RouteData RouteData { get; set; }
   9: }

如下所示的代码片段体现了RouterMiddleware处理请求的完整逻辑。我们在创建一个RouterMiddleware对象的时候需要指定一个Router对象,以及一个用来创建Logger的LoggerFactory。当这个中间件开始处理请求的时候,它会根据当前HttpContext创建一个RouteContext上下文对象,并将其作为参数调用Router的RotueAsync方法进行路由解析。如果在路由解析结束之后通过RouteContext的Handler属性返回的请求处理存在,意味着当前请求与注册的路由匹配,在此情况下它会将当前请求交给这个处理器做后续处理。在这之前它会从RouteContext上下文中提出出RouteData,然后据此创建一个RoutingFeature对象并附加到HttpContext上面。

   1: public class RouterMiddleware
   2: {
   3:     private ILogger             _logger;
   4:     private RequestDelegate     _next;
   5:     private IRouter             _router;
   6:  
   7:     public RouterMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IRouter router)
   8:     {
   9:         _next       = next;
  10:         _logger     = loggerFactory.CreateLogger<RouterMiddleware>();
  11:         _router     = router;
  12:     }
  13:  
  14:     public async Task Invoke(HttpContext context)
  15:     {
  16:         RouteContext routeContext = new RouteContext(context);
  17:         routeContext.RouteData.Routers.Add(_router);
  18:         await _router.RouteAsync(routeContext);
  19:         if (null == routeContext.Handler)
  20:         {
  21:             _logger.LogDebug(1, "Request did not match any routes.");
  22:             await _next(context);
  23:         }
  24:         else
  25:         {
  26:             context.Features.Set<IRoutingFeature>(new RoutingFeature {  RouteData = routeContext.RouteData})
  27:             await routeContext.Handler(context);
  28:         }
  29:     }
  30: }

我们除了可以调用HttpContext的扩展方法GetRouteData得到封装了路由参数的RouteData对象之前,我们还可以调用另一个名为GetRouteValue发的扩展方法直接获取某个路由参数的值。在如下所示的代码片段中,我们采用比较简单代码展示了这两个扩展放的实现。

   1: public static class RoutingHttpContextExtensions
   2: {
   3:     public static RouteData GetRouteData(this HttpContext context)
   4:     {
   5:         return context.Features.Get<IRoutingFeature>()?.RouteData;
   6:     }
   7:  
   8:     public static object GetRouteValue(this HttpContext context, string key)
   9:     {
  10:         return context.GetRouteData()?.Values[key];
  11:     }
  12: }

一般来说我们倾向于调用ApplicationBuilder的扩展方法UseRouter来注册RouterMiddleware中间件。具体来说,我们可以选择如下两个UseRouter方法重载。如果调用第一个重载,我们需要为注册的RouterMiddleware中间件提供一个具体的Router对象。对于第二个重载来说,这个Router对象实际上是利用RouteBuilder创建的,我们在调用这个方法的时候需要以Action<IRouteBuilder>对象的形式利用这个RouteBuilder注册所需的路由。

   1: public static class RoutingBuilderExtensions
   2: {
   3:     public static IApplicationBuilder UseRouter(this IApplicationBuilder builder, IRouter router)
   4:     {
   5:         return builder.UseMiddleware<RouterMiddleware>(new object[] { router });
   6:     }
   7:  
   8:     public static IApplicationBuilder UseRouter(this IApplicationBuilder builder, Action<IRouteBuilder> action)
   9:     {       
  10:         RouteBuilder routeBuilder = new RouteBuilder(builder);
  11:         action(routeBuilder);
  12:         return builder.UseRouter(routeBuilder.Build());
  13:     }
  14: }

 


ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系
ASP.NET Core的路由[2]:路由系统的核心对象——Router
ASP.NET Core的路由[3]:Router的创建者——RouteBuilder
ASP.NET Core的路由[4]:来认识一下实现路由的RouterMiddleware中间件
ASP.NET Core的路由[5]:内联路由约束的检验
作者:蒋金楠
微信公众账号:大内老A
微博: www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号 蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
3月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
9月前
|
开发框架 .NET 开发者
简化 ASP.NET Core 依赖注入(DI)注册-Scrutor
Scrutor 是一个简化 ASP.NET Core 应用程序中依赖注入(DI)注册过程的开源库,支持自动扫描和注册服务。通过简单的配置,开发者可以轻松地从指定程序集中筛选、注册服务,并设置其生命周期,同时支持服务装饰等高级功能。适用于大型项目,提高代码的可维护性和简洁性。仓库地址:&lt;https://github.com/khellang/Scrutor&gt;
223 5
|
10月前
|
开发框架 .NET C#
在 ASP.NET Core 中创建 gRPC 客户端和服务器
本文介绍了如何使用 gRPC 框架搭建一个简单的“Hello World”示例。首先创建了一个名为 GrpcDemo 的解决方案,其中包含一个 gRPC 服务端项目 GrpcServer 和一个客户端项目 GrpcClient。服务端通过定义 `greeter.proto` 文件中的服务和消息类型,实现了一个简单的问候服务 `GreeterService`。客户端则通过 gRPC 客户端库连接到服务端并调用其 `SayHello` 方法,展示了 gRPC 在 C# 中的基本使用方法。
198 5
在 ASP.NET Core 中创建 gRPC 客户端和服务器
|
9月前
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
181 1
|
9月前
|
开发框架 缓存 .NET
GraphQL 与 ASP.NET Core 集成:从入门到精通
本文详细介绍了如何在ASP.NET Core中集成GraphQL,包括安装必要的NuGet包、创建GraphQL Schema、配置GraphQL服务等步骤。同时,文章还探讨了常见问题及其解决方法,如处理复杂查询、错误处理、性能优化和实现认证授权等,旨在帮助开发者构建灵活且高效的API。
222 3
|
11月前
|
开发框架 JavaScript 前端开发
一个适用于 ASP.NET Core 的轻量级插件框架
一个适用于 ASP.NET Core 的轻量级插件框架
159 0
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
377 0
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
197 7
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
216 0
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
162 0

热门文章

最新文章