Asp.NetCore 自定义中间件
这节演示一下自定义中间件,第一节我们讲到,中间件的处理流程就像一个俄罗斯套娃,那这种俄罗斯套娃型的流程内部是如何实现的呢,下面请看代码。
第一种写法是直接写在Configure方法中的,使用app.Use(委托)配合lambda表达式使用,适合很轻量级的中间件。
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("CustomerMiddleWare1-in\n");
await next();
await context.Response.WriteAsync("CustomerMiddleWare1-out");
});
微软约定中间件需要两个参数,一个是httpcontext上下文对象,一个是Task类型的委托。通过上下文对象,处理请求,通过委托传递上下文对象到下一个中间件(这也是套娃模式的由来)。
这也限制了方法,必须是异步的async方法,调用next()之后,上下文对象发送给下一中间件了,该方法就会处于等待状态,直到后续的中间件处理完毕,返回后,再执行next()方法之后的代码。(关于同步和异步的有关知识,将在后续进行讲解)
除了使用Use()方法,还有一种用法,这个方法有点特殊,因为它不存在next()方法传递上下文对象,它是请求管道的底,用于直接返回响应
//run 是终端中间件,他是没有next()方法的,只要进入这个中间件,后续的中间件都不会执行了,从它这里请求完毕原路返回
app.Run(async context =>
{
await context.Response.WriteAsync("I am End MiddleWare\n");
});
.NetCore 3.x推出了一个新的中间件,叫EndPoints
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
它跟Run()一样,是兜底的中间件,但是用法比较特殊了,微软给我们的默认配置就是直接路由到某一页面,一般是网站首页。
下面看一下运行结果的演示,有如下三个中间件:
//use是添加中间中间件,就是处理完了,继续传给下一个中间件,它有next()委托
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("CustomerMiddleWare1-in\n");
await next();
await context.Response.WriteAsync("CustomerMiddleWare1-out");
});
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("CustomerMiddleWare2-in\n");
await next();
await context.Response.WriteAsync("CustomerMiddleWare2-out\n");
});
//run 是终端中间件,他是没有next()方法的,只要进入这个中间件,后续的中间件都不会执行了,从它这里请求完毕原路返回
app.Run(async context =>
{
await context.Response.WriteAsync("I am End MiddleWare\n");
});
运行结果为:

这很直观的反应了中间件的顺序执行,以及嵌套执行
下面看一下如何定义一个真正的自定义中间件
首先,我们要明确,微软规定的自定义中间件的要求
1.具有类型为RequestDelegate参数的公共构造函数,这个参数就是请求委托,它在一个个的中间件中传递
2.具有Invoke或者InvokeAsync的方法,该方法的返回值必须是Task,而且第一个参数必须是HttpContext
public class MyMiddleWare
{
private readonly RequestDelegate _next; public MyMiddleWare( RequestDelegate next )
{
_next = next;
} public async Task InvokeAsync(HttpContext context)
{
//此处写中间件业务逻辑
//然后调用next指向下一个中间件
//调用next之前,属于请求部分的处理
await _next(context);
//next执行完毕之后,属于相应部分的处理
}
}
定义完成以后,使用UseMiddleware<中间件>()将自定义中间件添加进来
app.UseMiddleware<MyMiddleWare>();
但这样的用法,还是少了一点优雅与灵活性,我们可以通过扩展方法的形式,为IApplicationBuilder添加扩展方法,实现自定义中间件添加与配置的灵活应用(扩展方法在之前的文章中有讲)
public static class MyMiddleWareExtension
{
public static IApplicationBuilder UseMymiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<MyMiddleWare>();
}
}
这样的话,就可以直接调用方法添加中间件了
//使用扩展方法的形式,添加自定义中间件然后可以通过构造方法的形式,传递配置参数
app.UseMymiddleware();
初学者可对此做初步了解,对其中设计的代码语法知识,是必须要掌握的。另外,如果需要查看ASP.NetCore的源码,请访问https://github.com/dotnet/aspnetcore自行下载或克隆到本地
这是我公众号二维码,最新的文章会同步至此

Asp.NetCore 自定义中间件的更多相关文章
- ASP.NET Core 1.1 静态文件、路由、自定义中间件、身份验证简介
概述 之前写过一篇关于<ASP.NET Core 1.0 静态文件.路由.自定义中间件.身份验证简介>的文章,主要介绍了ASP.NET Core中StaticFile.Middleware ...
- ASP.NET Core 中间件自定义全局异常处理
目录 背景 ASP.NET Core过滤器(Filter) ASP.NET Core 中间件(Middleware) 自定义全局异常处理 .Net Core中使用ExceptionFilter .Ne ...
- 跟我一起学.NetCore之中间件(Middleware)应用和自定义
前言 Asp.NetCore中的请求管道是通过一系列的中间件组成的,使得请求会根据需求进行对应的过滤和加工处理.在平时开发中会时常引用别人定义好的中间件,只需简单进行app.Usexxx就能完成中间件 ...
- Asp.NetCore Web应用程序中的请求管道和中间件
你是否会迷惑当我们请求一个ASP.NetWeb应用程序以后,它是怎么处理这些请求的,后台是怎么工作的,今天就讲一下Asp.NetCore Web应用程序中的请求处理过程. 上一节,我们讲到,Start ...
- ASP.NET Core 1.0 静态文件、路由、自定义中间件、身份验证简介
概述 ASP.NET Core 1.0是ASP.NET的一个重要的重新设计. 例如,在ASP.NET Core中,使用Middleware编写请求管道. ASP.NET Core中间件对HttpCon ...
- asp.net core中写入自定义中间件
首先要明确什么是中间件?微软官方解释:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?tabs=aspnet ...
- 如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容?
原文:如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容? 文章名称: 如何在ASP.NET Core自定义中间件读取Request.Body和 ...
- Asp.Net Core入门之自定义中间件
什么是中间件? 这里引用官方解释: 中间件是用于组成应用程序管道来处理请求和响应的组件.管道内的每一个组件都可以选择是否将请求交给下一个组件.并在管道中调用下一个组件之前和之后执行某些操作.请求委托被 ...
- asp.net core 3.1 自定义中间件实现jwt token认证
asp.net core 3.1 自定义中间件实现jwt token认证 话不多讲,也不知道咋讲!直接上代码 认证信息承载对象[user] /// <summary> /// 认证用户信息 ...
随机推荐
- linux中c语言编程main函数和参数
linux下main函数的的标准调用函数的标准形式 int main(int char,char *argv[]) 在main函数的两个参数中,argc必须是整型变量,其是命令行的参数的数目,argv ...
- 6、Spring教程之自动装配
自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean. Spring中bean有三种装配机制,分别是: 在xml中显式配置 ...
- linux软件管理之yum管理操作软件包
什么是rpm 1.1`RPM` 全称 `RedHat Package Manager` 缩写,由红帽开发用于软件包的安装.升级.卸载与查询. 1.2rpm包名组成部分 `RPM` 包命名以-将软件分成 ...
- SpringBoot-03 yaml+JSR303
SpringBoot-03 yaml+JSR303 Yaml 1.配置文件 SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的 YAML是 "YAML Ain't a Ma ...
- java例题_43 求0—7所能组成的奇数个数
1 /*43 [程序 43 求奇数个数] 2 题目:求 0-7 所能组成的奇数个数. 3 */ 4 5 /*分析 6 * 1.0不能作最高位且最低位只能是1,3,5,7; 7 * 2.没有限定是几位数 ...
- vue-router 监控全局路由,在路由中改变vuex中的状态值
- JavaCV 采集摄像头和麦克风数据推送到流媒体服务器
越来越觉得放弃JavaCV FFmpeg native API,直接使用JavaCV二次封装的API开发是很明智的选择,使用JavaCV二次封装的API开发避免了各种内存操作不当引起的crash. 上 ...
- 开源服务器设计总计(plain framework2020年总计)
2020年注定会被历史铭记,世界遭受着一场前所未有的灾难,这种灾难到现在还在持续.还记得19年末的时候,那时候听到一点点消息,哪里想得到年关难过,灾难来的让人猝不及防.由于疫情防控,2020年感觉转瞬 ...
- [Fundamental of Power Electronics]-PART II-7. 交流等效电路建模-7.4 规范电路模型
7.4 规范电路模型 在讨论了推导开关变换器交流等效电路模型的几种方法后,让我们先停下来,说明下这些结果.所有的在 CCM下以PWM工作的DC-DC变换器都具有相似的基本功能.首先,他们在理想情况下, ...
- 【Azure 微服务】Service Fabric中微服务在升级时,遇见Warning - System.Collections.Generic.KeyNotFoundException 服务无法正常运行
问题描述 使用.Net Framework 4.5.2为架构的Service Fabric微服务应用,在升级后发布到Azure Fabric中,服务无法运行.通过Service Fabric Expl ...