.NET Core开发实战(第21课:中间件:掌控请求处理过程的关键)--学习笔记(下)
21 | 中间件:掌控请求处理过程的关键
如果在 Map 的时候逻辑复杂一点,不仅仅判断它的 URL 地址,而且要做特殊的判断的话,可以这么做把判断逻辑变成一个委托
我们要判断当我们的请求地址包含 abc 的时候,输出 new abc
app.MapWhen(context =>
{
return context.Request.Query.Keys.Contains("abc");
}, builder =>
{
builder.Run(async context =>
{
await context.Response.WriteAsync("new abc");
});
});
启动程序,没有任何输出
当我们在默认启动地址后面输入 ?abc=1 的时候,可以看到输出了 new abc
这里用到了一个 Run 的方法,上一节用到的是 Use 方法
app.Map("/abc", abcBuilder =>
{
abcBuilder.Use(async (context, next) =>
{
//await context.Response.WriteAsync("Hello");
await next();
await context.Response.WriteAsync("Hello2");
});
});
Run 和 Use 的区别是什么呢?
Use 是指我们可以像注册一个完整的中间件一样,将 next 注入进来,我们可以去决定是否执行后续的中间件
Run 的含义就表示我们这里就是中间件执行的末端,也就不在执行后面的中间件了,在这里将返回请求
那我们如何像 UseRouting UseEndpoints 一样来设计我们自己的中间件呢?
这里定义好了一个 MyMiddleware
namespace MiddlewareDemo.Middlewares
{
class MyMiddleware
{
RequestDelegate _next;
ILogger _logger;
public MyMiddleware(RequestDelegate next, ILogger<MyMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
using (_logger.BeginScope("TraceIdentifier:{TraceIdentifier}", context.TraceIdentifier))
{
_logger.LogDebug("开始执行");
await _next(context);
_logger.LogDebug("执行结束");
}
}
}
}
定义中间件是用了一个约定的方式,中间件的类包含一个方法 Invoke 或者 InvokeAsync 这样一个方法,它的返回是一个 Task,入参是一个 HttpContext,实际上可以理解成与中间件的委托是一样的,只要我们的类包含这样一个方法,就可以把它作为一个中间件注册进去,并被框架识别到
这里还定义了一个 MyBuilderExtensions
namespace Microsoft.AspNetCore.Builder
{
public static class MyBuilderExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<MyMiddleware>();
}
}
}
把我们的中间件注册进去,这个方法就是 UseMyMiddleware
通过这样的定义,我们就可以使用自己的中间件
app.UseMyMiddleware();
启动程序,输出如下:
控制台输出
dbug: MiddlewareDemo.Middlewares.MyMiddleware[0]
=> RequestPath:/weatherforecast RequestId:0HLU50UEM3M9F:00000001, SpanId:|77f92fe8-4a6d800968327989., TraceId:77f92fe8-4a6d800968327989, ParentId: => TraceIdentifier:0HLU50UEM3M9F:00000001
开始执行
dbug: MiddlewareDemo.Middlewares.MyMiddleware[0]
=> RequestPath:/weatherforecast RequestId:0HLU50UEM3M9F:00000001, SpanId:|77f92fe8-4a6d800968327989., TraceId:77f92fe8-4a6d800968327989, ParentId: => TraceIdentifier:0HLU50UEM3M9F:00000001
执行结束
网页控制器输出
[{"date":"2020-03-11T23:30:55.3411696+08:00","temperatureC":20,"temperatureF":67,"summary":"Warm"},{"date":"2020-03-12T23:30:55.3417863+08:00","temperatureC":52,"temperatureF":125,"summary":"Bracing"},{"date":"2020-03-13T23:30:55.3417916+08:00","temperatureC":-3,"temperatureF":27,"summary":"Mild"},{"date":"2020-03-14T23:30:55.341792+08:00","temperatureC":35,"temperatureF":94,"summary":"Balmy"},{"date":"2020-03-15T23:30:55.3417923+08:00","temperatureC":37,"temperatureF":98,"summary":"Sweltering"}]Hello2
如果要实现一个断路器,就是不执行后续逻辑,注释掉一行
_logger.LogDebug("开始执行");
//await _next(context);
_logger.LogDebug("执行结束");
启动程序,页面不会输出任何内容,只会在控制台打印出中间件的执行过程,后续的控制器不会执行
这样就实现了一个断路器,也就意味着可以使用自己的中间件做请求的控制,而且时非常灵活的控制
在使用中间件的过程中,需要非常注意的是注册中间件的顺序,这些顺序就决定了中间件执行的时机,某些中间件会是断路器的作用,某些中间件会做一些请求内容的处理
还有一个比较关键的要点是指应用程序一旦开始向 Response write 的时候,后续的中间件就不能再去操作它的 header,这一点是需要注意的
可以通过 Context.Response.HasStarted 来判断是否已经开始向响应的 body 输出内容,一旦输出了内容,就不要再操作 header
GitHub源码链接:
https://github.com/MingsonZheng/DotNetCoreDevelopmentActualCombat/tree/main/MiddlewareDemo



本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
.NET Core开发实战(第21课:中间件:掌控请求处理过程的关键)--学习笔记(下)的更多相关文章
- [ASP.NET Core开发实战]基础篇03 中间件
什么是中间件 中间件是一种装配到应用管道,以处理请求和响应的组件.每个中间件: 选择是否将请求传递到管道中的下一个中间件. 可在管道中的下一个中间件前后执行. ASP.NET Core请求管道包含一系 ...
- 2月送书福利:ASP.NET Core开发实战
大家都知道我有一个公众号“恰童鞋骚年”,在公众号2020年第一天发布的推文<2020年,请让我重新介绍我自己>中,我曾说到我会在2020年中每个月为所有关注“恰童鞋骚年”公众号的童鞋们送一 ...
- [ASP.NET Core开发实战]开篇词
前言 本系列课程文章主要是学习官方文档,再输出自己学习心得,希望对你有所帮助. 课程大纲 本系列课程主要分为三个部分:基础篇.实战篇和部署篇. 希望通过本系列课程,能让大家初步掌握使用ASP.NET ...
- CSS高效开发实战:CSS 3、LESS、SASS、Bootstrap、Foundation --读书笔记(1)设定背景图
技术的新发展,除计算机可以接入互联网之外,平板电脑.智能手机.智能电视等其他设备均可访问互联网.在多设备时代,构建多屏体验也不是听说的那么难. 但是这也增加了学习CSS的难度?不知道如何上手,只懂一点 ...
- .NET Core开发实战(第11课:文件配置提供程序)--学习笔记
11 | 文件配置提供程序:自由选择配置的格式 文件配置提供程序 Microsoft.Extensions.Configuration.Ini Microsoft.Extensions.Configu ...
- [ASP.NET Core开发实战]基础篇01 Startup
Startup,顾名思义,就是启动类,用于配置ASP.NET Core应用的服务和请求管道. Startup有两个主要作用: 通过ConfigureServices方法配置应用的服务.服务是一个提供应 ...
- 2、SpringBoot接口Http协议开发实战8节课(1-6)
1.SpringBoot2.xHTTP请求配置讲解 简介:SpringBoot2.xHTTP请求注解讲解和简化注解配置技巧 1.@RestController and @RequestMapping是 ...
- [ASP.NET Core开发实战]基础篇02 依赖注入
ASP.NET Core的底层机制之一是依赖注入(DI)设计模式,因此要好好掌握依赖注入的用法. 什么是依赖注入 我们看一下下面的例子: public class MyDependency { pub ...
- 2、SpringBoot接口Http协议开发实战8节课(7-8)
7.SpringBoot2.x文件上传实战 简介:讲解HTML页面文件上传和后端处理实战 1.讲解springboot文件上传 MultipartFile file,源自SpringMVC 1)静态页 ...
- [ASP.NET Core开发实战]基础篇06 配置
配置,是应用程序很重要的组成部分,常常用于提供信息,像第三方应用登录钥匙.上传格式与大小限制等等. ASP.NET Core提供一系列配置提供程序读取配置文件或配置项信息. ASP.NET Core项 ...
随机推荐
- 从头到尾创建一个vue项目
- Qt开发-共享内存使用范例,配合开发者密钥使用后台调试程序或者进入调试模式
共享内存 就之前不是开发了一个Leventure_DeveloperKey用以调试程序嘛,在这里简单聊一下调试模式的方案. 这里的调试分为了两种,一种是调试模式,一种是开发者模式.需要这两种模式的原因 ...
- CDC设计实例-01
CDC设计实例 Clock Gating Cell & Glitch Free Clock Switch(门控单元和动态切换时钟) 一个电路有多个时钟输入进来,希望在工作当中能够动态切换时钟; ...
- 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.11.23)
一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...
- [转帖]自动清理_详解centos7和centos6系统的/tmp目录自动清理规则及区别
概述 分享最近应用碰到的一个奇怪bug,一开始以为是代码上的问题,找了一段时间发现居然是因为系统的一个自动清理规则导致,下面一起来看看吧~ 一.应用报错: logwire.core.exception ...
- 银河麒麟在线升级新版本docker
银河麒麟在线升级新版本docker 卸载 学习来自: https://cloud.tencent.com/developer/article/1491742 yum remove docker \ d ...
- [转帖]decimal and numeric (Transact-SQL)
https://learn.microsoft.com/en-us/sql/t-sql/data-types/decimal-and-numeric-transact-sql?view=sql-ser ...
- [转帖]Kafka-Kraft 模式架构部署
news文章来源: Kafka-Kraft 模式架构部署 Kafka网址:https://kafka.apache.org/ PS:因环境原因此文档内端口都有修改! 1.去官网下载二进制包 PS:3. ...
- 国产CPU制造工艺与部分性能总结
国产CPU制造工艺与部分性能总结 背景 最近一段时间验证了很多国产CPU的性能. 感觉很多地方与之前的理解有一些偏差. 前几天总结了部分架构和指令集相关的差异 今天想着总结一下制造相关的部分. 希望能 ...
- 【技术剖析】7. 看看毕昇 JDK 团队是如何解决 JVM 中 CMS 的 Crash
[技术剖析]7. 看看毕昇 JDK 团队是如何解决 JVM 中 CMS 的 Crashhttps://bbs.huaweicloud.com/forum/thread-168485-1-1.html ...