asp.net core mvc 中间件之路由

简介: asp.net core mvc 中间件之路由路由中间件首先看路由中间件的源码先用httpContext实例化一个路由上下文,然后把中间件接收到的路由添加到路由上下文的路由集合然后把路由上下文作为参数,调用IRouter.

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
  • RouteHandlerMvcRouteHandler都可以作为routeBuilder.DefaultHandler,以提供Route类实例化需要的参数。RouteHandlerRouteAsync方法直接给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
用心做好每一件事,结果会给你最大的惊喜!
目录
相关文章
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
811 5
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
500 1
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
496 7
|
缓存 中间件 网络架构
Python Web开发实战:高效利用路由与中间件提升应用性能
在Python Web开发中,路由和中间件是构建高效、可扩展应用的核心组件。路由通过装饰器如`@app.route()`将HTTP请求映射到处理函数;中间件则在请求处理流程中插入自定义逻辑,如日志记录和验证。合理设计路由和中间件能显著提升应用性能和可维护性。本文以Flask为例,详细介绍如何优化路由、避免冲突、使用蓝图管理大型应用,并通过中间件实现缓存、请求验证及异常处理等功能,帮助你构建快速且健壮的Web应用。
282 1
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
406 0
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
422 0
|
开发框架 中间件 .NET
分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法
分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法
1028 0
|
消息中间件 存储 中间件
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
14891 1
|
消息中间件 编解码 Docker
Docker部署RabbitMQ消息中间件
【7月更文挑战第4天】Docker部署RabbitMQ消息中间件
638 3