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> /// 认证用户信息 ...
随机推荐
- Elasticsearch 单字符串多字段查询
前言 有些时候,我们搜索的时候,只会提供一个输入框,但是会查询相关的多个字段,典型的如Google搜索,我们该如何用 Elasticsearch 如何实现呢? 实例 从单字符串查询的实例说起 创建测试 ...
- Envoy 部署类型
目录 Envoy 网络拓扑及请求流程 1. 术语 2. 网络拓扑 3. 配置 4. 更高层的架构 5. 请求流程 1. Listener TCP 接收 2. 侦听器过滤器链和网络过滤器链匹配 3.TL ...
- 蛇形填数(JAVA语言)
package 第三章; import java.util.Scanner; public class 蛇形填数 { public static void main(String[] args) { ...
- WebGPU[1] 三角形
代码见: https://github.com/onsummer/my-dev-notes/tree/master/webgpu-Notes/01-triangle 如果本篇的代码不能跑了,请联系我或 ...
- Android学习之在Adapter中调用Fragment
•前言 在学习<第一行代码>,4.5 小节--一个简易版的新闻应用的时候: 在为 RecyclerView 创建适配器的时候: 作者直接在 NewsTitleFragment.java 中 ...
- mybatis-plus的Could not set property 'updateDate' of 'class com.example.pojo.User' with value 'Fri Jul 24 10:29:39 CST 2020' Cause: java.lang.IllegalArgumentException: argument type mismatch解决方案
按照官网在写mybatis-plus的自动填充功能一直报错,发现官网的解说不全,数据库是datetime类型,java程序又是date,类型不匹配 org.mybatis.spring.MyBatis ...
- 仅仅使用Google就完成了人生第一次破解
2021年2月6日21:17:09 begin 起因 在异乡的打工人,不善言谈,幸有一老同学,周末常邀吃饭,感恩之心铭记于心.她结婚时,为表心意欲做视频,视频需要制作字幕,搜索之,偶遇一字幕软件,但是 ...
- [Fundamental of Power Electronics]-PART II-8. 变换器传递函数-8.1 Bode图回顾
8.0 序 工程设计过程主要包括以下几个过程: 1.定义规格与其他设计目标 2.提出一个电路.这是一个创造性的过程,需要利用工程师的实际见识和经验. 3.对电路进行建模.变换器的功率级建模方法已经在第 ...
- 剑指offer刷题
1.面试题43. 1-n整数中1出现的次数 输入一个整数 n ,求1-n这n个整数的十进制表示中1出现的次数. 例如,输入12,1-12这些整数中包含1 的数字有1.10.11和12,1一共出现了5次 ...
- buuctf pwn wp---part1
pwn难啊 1.test_your_nc 测试你nc,不用说,连上就有. 2.rip ida中已经包含了system函数: 溢出,覆盖rip为fun函数,peda计算偏移为23: from pwn i ...