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实际上也是继承自IRouterRouteHandler和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
asp.net core mvc 中间件之路由的更多相关文章
- asp.net core mvc 中间件之WebpackDevMiddleware
asp.net core mvc 中间件之WebpackDevMiddleware WebpackDevMiddleware中间件主要用于开发SPA应用,启用Webpack,增强网页开发体验.好吧,你 ...
- ASP.NET Core MVC 配置全局路由前缀
前言 大家好,今天给大家介绍一个 ASP.NET Core MVC 的一个新特性,给全局路由添加统一前缀.严格说其实不算是新特性,不过是Core MVC特有的. 应用背景 不知道大家在做 Web Ap ...
- 【转】ASP.NET Core MVC 配置全局路由前缀
本文地址:http://www.cnblogs.com/savorboard/p/dontnet-IApplicationModelConvention.html作者博客:Savorboard 前言 ...
- 第二十一节:Asp.Net Core MVC和WebApi路由规则的总结和对比
一. Core Mvc 1.传统路由 Core MVC中,默认会在 Startup类→Configure方法→UseMvc方法中,会有默认路由:routes.MapRoute("defaul ...
- asp.net core mvc剖析:路由
在mvc框架中,任何一个动作请求都会被映射到具体控制器中的方法上,那框架是如何完成这样一个过程的,现在我们就来简单分析下流程. 我们紧跟上面的主题,任何一个请求都会交给处理管道进行处理,那mvc处理的 ...
- ASP.NET Core 入门教程 3、ASP.NET Core MVC路由入门
一.前言 1.本文主要内容 ASP.NET Core MVC路由工作原理概述 ASP.NET Core MVC带路径参数的路由示例 ASP.NET Core MVC固定前/后缀的路由示例 ASP.NE ...
- ASP.NET Core 入门笔记4,ASP.NET Core MVC路由入门
敲了一部分,懒得全部敲完,直接复制大佬的博客了,如有侵权,请通知我尽快删除修改 摘抄自https://www.cnblogs.com/ken-io/p/aspnet-core-tutorial-mvc ...
- asp.net core mvc 管道之中间件
asp.net core mvc 管道之中间件 http请求处理管道通过注册中间件来实现各种功能,松耦合并且很灵活 此文简单介绍asp.net core mvc中间件的注册以及运行过程 通过理解中间件 ...
- ASP.NET Core MVC的路由参数中:exists后缀有什么作用,顺便谈谈路由匹配机制
我们在ASP.NET Core MVC中如果要启用Area功能,那么会看到在Startup类的Configure方法中是这么定义Area的路由的: app.UseMvc(routes => { ...
随机推荐
- jquery Nestable 获取改变排序后的json数据 拖动排序
<script type="text/javascript"> jQuery(function($){ $('.dd').nestable(); $('.dd-hand ...
- windows 与 Linux SOCKET通讯
windows client 端口 // Def_win_client_socket_test.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" ...
- phantomjs问题收集
1. phantomjs如果遇到重定向的url,两个页面都会加载,onInitialized只会执行一次,onResourceReceived会执行两次.我试过在onInitialized加一段代码, ...
- Aspose.Words给word文档加水印
需求:在一些重要的Word文档需要打印时,添加水印以明出处. 方案:使用Aspose组件给word文档 代码:干货如下 /// <summary> /// Inserts a waterm ...
- Python内置的subprocess.Popen对象
具体内容参见:https://docs.python.org/3/library/subprocess.html 大概来说,就是可以对应输入的命令产生一个进程,该进程实例内置如下方法. | comm ...
- python中的open( )函数
函数原型 open(file, mode=‘r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True) buff ...
- SpringMVC 学习 九 SSM环境搭建 (二) Spring配置文件的编写
spring配置文件中需要干的事情 (一)开启 Service与pojo包的注解扫描 注意:spring 扫描与表对应的实体类,以及service层的类,不能用来扫描Controller层的类,因为 ...
- kbmMW均衡负载与容灾(3)(转载红鱼儿)
在kbmMW均衡负载与容灾(1)中,介绍了利用ClientTransport的OnReconnect事件,对联接的应用服务器的地址进行更换,做容灾处理.实际上,作者还给我们提供了另外一种机制,直接在C ...
- 导入CA证书报错 keytool error: java.lang.Exception: Input not an X.509 certificate
导入CA证书报错: keytool error: java.lang.Exception: Input not an X.509 certificate 如果你的CA证书是如下格式的: -----BE ...
- vue 开发系列(五) 调用原生API
概要 我们在开发手机端程序的时候了,我们经常需要使用到拍照,二维码的功能.数字天堂公司提供了大量的原生API支持. http://www.html5plus.org/doc/ 实现 1.在hbuild ...