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> /// 认证用户信息 ...
随机推荐
- 2019HDU多校第七场 HDU6656 Kejin Player H 【期望递归】
一.题目 Kejin Player H 二.分析 因为在当前等级$i$,如果升级失败可能会退回到原来的某一等级$x$,相当于就是失败的期望就是$E + (Sum[i-1] - Sum[x-1]) + ...
- ResNet的个人总结
ResNet可以说是我认真读过的第一篇paper,据师兄说读起来比较简单,没有复杂的数学公式,不过作为经典的网络结构还是有很多细节值得深究的.因为平时不太读英文文献,所以其实读的时候也有很多地方不是很 ...
- 【博弈论】组合游戏及SG函数浅析
目录 预备知识 普通的Nim游戏 SG函数 预备知识 公平组合游戏(ICG) 若一个游戏满足: 由两名玩家交替行动: 游戏中任意时刻,合法操作集合只取决于这个局面本身: 若轮到某位选手时,若该选手无合 ...
- 攻防世界 reverse 进阶 8-The_Maya_Society Hack.lu-2017
8.The_Maya_Society Hack.lu-2017 在linux下将时间调整为2012-12-21,运行即可得到flag. 下面进行分析 1 signed __int64 __fastca ...
- 在ASP.NET Core中用HttpClient(四)——提高性能和优化内存
到目前为止,我们一直在使用字符串创建请求体,并读取响应的内容.但是我们可以通过使用流提高性能和优化内存.因此,在本文中,我们将学习如何在请求和响应中使用HttpClient流. 什么是流 流是以文件. ...
- 冒泡排序(BubbleSort)
介绍: 冒泡排序是一种最基础的交换排序(两两比较待排序的关键字,交换不满足次序要求的那对数,直到整个表都满足次序要求为止),工作方式如同碳酸饮料中的二氧化碳气泡最终会上浮到顶端一样,故名"冒 ...
- PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 凌宸1642
PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) 目录 PAT (Basic Level) Practice (中文) 1050 螺旋矩阵 (25 分) ...
- angularjs 图片上传
<input type="file" file-model="myFile"/><div class="col-md-12" ...
- [Fundamental of Power Electronics]-PART I-2.稳态变换器原理分析-2.1 引言
2.1 引言 在上一章中,介绍了降压变换器作为降低直流电压的一种方法,其仅使用非耗散开关,电感器和电容器.开关状态变换产生一个矩形波形\(v_{s}(t)\),如图2.1所示.当开关位于位置1时,该电 ...
- java正则匹配${xxx} 排除单引号双引号内的内容,前提引号必须成对出现
public static void main(String[] a) { String wpp = "select 1, ${mark} '``this is, `/message22` ...