asp.net core mvc 中间件之路由
asp.net core mvc 中间件之路由
路由中间件
- 首先看路由中间件的源码
- 先用
httpContext
实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合 - 然后把路由上下文作为参数,调用
IRouter.RouteAsync
方法,该方法主要是进行路由匹配,匹配成功后给context.Handler
赋值 - 如果路由匹配成功,且handler不为空,说明已经有了后续处理消息的通道,就不用走下一个中间件了,否则消息处理交给下一个中间件
- MVC流程就是从这里开始,路由匹配成功后,从handler进入MVC流程
namespace Microsoft.AspNetCore.Builder { public class RouterMiddleware { private readonly ILogger _logger; private readonly RequestDelegate _next; private readonly IRouter _router; public RouterMiddleware( RequestDelegate next, ILoggerFactory loggerFactory, IRouter router) { _next = next; _router = router; _logger = loggerFactory.CreateLogger<RouterMiddleware>(); } public async Task Invoke(HttpContext httpContext) { var context = new RouteContext(httpContext); context.RouteData.Routers.Add(_router); await _router.RouteAsync(context); if (context.Handler == null) { _logger.RequestDidNotMatchRoutes(); await _next.Invoke(httpContext); } else { httpContext.Features[typeof(IRoutingFeature)] = new RoutingFeature() { RouteData = context.RouteData, }; await context.Handler(context.HttpContext); } } } }
路由
-
IRouter
接口仅定义了两个方法,其中路由的核心在于RouteAsync
方法,该方法可用于路由匹配,返回处理委托 -
RouteBase
抽象类的的RouteAsync
方法进行路由的匹配,Route
类的RouteAsync
方法仅仅是执行了构造函数传进来的routeBuilder.DefaultHandler
路由的RouteAsync
方法,DefaultHandler
实际上也是继承自IRouter
-
RouteHandler
和MvcRouteHandler
都可以作为routeBuilder.DefaultHandler
,以提供Route
类实例化需要的参数。RouteHandler
的RouteAsync
方法直接给context.Handler
赋值从构造函数接收到的委托。 -
MvcRouteHandler``RouteAsync
方法则先根据匹配到的路由从已注册的控制器中适配方法,然后得到actionDescriptor
,包含http上下文以及方法的基本信息,最后直接给context.Handler
赋值,MVC流程从invoker.InvokeAsync()
开始
public Task RouteAsync(RouteContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } var candidates = _actionSelector.SelectCandidates(context); if (candidates == null || candidates.Count == 0) { _logger.NoActionsMatched(context.RouteData.Values); return Task.CompletedTask; } var actionDescriptor = _actionSelector.SelectBestCandidate(context, candidates); if (actionDescriptor == null) { _logger.NoActionsMatched(context.RouteData.Values); return Task.CompletedTask; } context.Handler = (c) => { var routeData = c.GetRouteData(); var actionContext = new ActionContext(context.HttpContext, routeData, actionDescriptor); if (_actionContextAccessor != null) { _actionContextAccessor.ActionContext = actionContext; } var invoker = _actionInvokerFactory.CreateInvoker(actionContext); if (invoker == null) { throw new InvalidOperationException( Resources.FormatActionInvokerFactory_CouldNotCreateInvoker( actionDescriptor.DisplayName)); } return invoker.InvokeAsync(); }; return Task.CompletedTask; }
路由注册
- 最常见的注册方法
app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });
总结
- 路由实际上就是根据请求链接,遍历路由模板进行匹配,匹配到了返回一个
Handler
用于后续处理消息 - 其中的匹配过程,除了模板匹配,还要进行方法匹配,最后才进入业务处理流程
- 总的来说,路由中间件就是调用
IRouter
实例的RouteAsync
方法,得到Handler
的话就执行,否则处理权交给下一个中间件。而路由实现,主要是匹配过程以及返回Handler
。到这里,就可以发散思维,做各种有趣的事了 - 以上是关于路由的知识梳理,看不懂没关系,这很正常,直接能看懂才怪了,进过实践,代码调试,都不能完全理解这个过程,而静下心来总结的时候,往往就能将零碎的知识点串联起来,打成一片,扫除盲点
持续更新,原文地址:https://www.cnblogs.com/xxred/p/9582200.html
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
优雅实现延时任务之Redis篇
什么是延时任务 延时任务,顾名思义,就是延迟一段时间后才执行的任务。举个例子,假设我们有个发布资讯的功能,运营需要在每天早上7点准时发布资讯,但是早上7点大家都还没上班,这个时候就可以使用延时任务来实现资讯的延时发布了。只要在前一天下班前指定第二天要发送资讯的时间,到了第二天指定的时间点资讯就能准时发出去了。如果大家有运营过公众号,就会知道公众号后台也有文章定时发送的功能。总而言之,延时任务的使用还是很广泛的。关于延时任务的实现方式,我知道的就不下于3种,后面会逐一介绍,今天就讲下如何用redis实现延时任务。 延时任务的特点 在介绍具体方案之前,我们不妨先想一下要实现一个延时系统,有哪些内容是必须存储下来的(这里的存储不一定是指持久化,也可以是放在内存中,取决于延时任务的重要程度)。首先要存储的就是任务的描述。假如你要处理的延时任务是延时发布资讯,那么你至少要存储资讯的id吧。另外,如果你有多种任务类型,比如:延时推送消息、延时清洗数据等等,那么你还需要存储任务的类型。以上总总,都归属于任务描述。除此之外,你还必须存储任务执行的时间点吧,一般来说就是时间戳。此外,我们还需要根据任务的...
- 下一篇
体验Django REST framework,解读REST架构风格
因为项目中使用了REST API,所以对REST架构风格做了一些研究。如果有对REST架构风格还不了解,或者一知半解的朋友,可以读读我的另一篇文章《那些年,我们一起误解过的REST》。 一开始在项目中使用的是OpenResty来实现REST API,但使用起来一直觉得不方便。主要是因为Lua没有ORM,也没有REST架构风格的框架。直到最近在用Django时,接触到Django REST framework,在深感便利的同时,也进一步加深了对REST架构风格的理解。所以写下这篇文章,一方面记录Django REST framework的体验过程,同时借此解读下REST架构风格。
相关文章
文章评论
共有0条评论来说两句吧...