.NET Core 3.0 中间件 Middleware
中间件官网文档解释:中间件是一种装配到应用管道以处理请求和响应的软件 每个中间件:
- 选择是否将请求传递到管道中的下一个组件。
- 可在管道中的下一个组件前后执行工作。
使用 IApplicationBuilder 创建中间件管道
ASP.NET Core 请求管道包含一系列请求委托,依次调用。 下图演示了这一概念。 沿黑色箭头执行。

IApplicationBuilder提供了三个扩展方法配置请求委托
- app.Run 作用添加一个终端中间件,因为不在向下传递请求,常常公开在管道末尾运行。实例代码
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, middleware!");
});
- app.Use 将多个请求委托链接在一起。next 参数表示管道中的下一个委托。 可通过不 调用 next 参数使管道短路等同于aap.run。 通常可在下一个委托前后执行操作,如以下示例所示:
app.Use(async (context, next) =>
{
// 传递前操作
await next.Invoke();
// 传递前操作
}); app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd delegate.");
});
}
- Map 扩展用作约定来创建管道分支。 Map 基于给定请求路径的匹配项来创建请求管道分支。 如果请求路径以给定路径开头,则执行分支。实例代码如下
private static void HandleMapTest1(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map Test 1");
});
} private static void HandleMapTest2(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("Map Test 2");
});
} public void Configure(IApplicationBuilder app)
{
app.Map("/map1", HandleMapTest1); app.Map("/map2", HandleMapTest2); app.Run(async context =>
{
await context.Response.WriteAsync("Hello from non-Map delegate. <p>");
});
}
自定义中间件
以下演示记录api输入输出参数的中间件。
1.创建一个webapi项目,在默认的WeatherForecastController控制器中添加一个简单的post方法,代码如下
[HttpPost]
public string PostWeatherForecast([FromBody]WeatherForecastA weatherForecastA)
{
return "添加成功";
}
public class WeatherForecastA
{
public int TemperatureC { get; set; }
}
2.新建一个中间件类.CS文件如图

选择之后默认代码如下:
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class LogReqResponseMiddleware
{
private readonly RequestDelegate _next; public LogReqResponseMiddleware(RequestDelegate next)
{
_next = next;
} public Task Invoke(HttpContext httpContext)
{ return _next(httpContext);
}
} // Extension method used to add the middleware to the HTTP request pipeline.
public static class LogReqResponseMiddlewareExtensions
{
public static IApplicationBuilder UseLogReqResponseMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<LogReqResponseMiddleware>();
}
}
脚手架自动帮我们创建一个 Invoke方法,传递给下一个中间件。一个将自定义的中间件添加到了http请求管道的扩展方法UseLogReqResponseMiddleware。
上面invoke不是异步的,我们自己可以改动,以下代码展示 一个api请求的输入参数和输出信息的日志打印
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class LogReqResponseMiddleware
{
private readonly RequestDelegate _next; public LogReqResponseMiddleware(RequestDelegate next)
{
_next = next;
} public async Task Invoke(HttpContext httpContext, ILogger<LogReqResponseMiddleware> logger)
{
var request = httpContext.Request;
request.EnableBuffering();
//把请求body流转换成字符串
string bodyAsText = await new StreamReader(request.Body).ReadToEndAsync();//记录请求信息
var requestStr = $"{request.Scheme} {request.Host}{request.Path} {request.QueryString} {bodyAsText}";
logger.LogDebug("Request:" + requestStr);
request.Body.Seek(0, SeekOrigin.Begin); var originalBodyStream = httpContext.Response.Body;
using (var responseBody = new MemoryStream())
{
httpContext.Response.Body = responseBody;
await _next(httpContext); var response = httpContext.Response;
response.Body.Seek(, SeekOrigin.Begin);
//转化为字符串
string text = await new StreamReader(response.Body).ReadToEndAsync();
//从新设置偏移量0
response.Body.Seek(, SeekOrigin.Begin); //记录返回值
var responsestr = $"{response.StatusCode}: {text}";
logger.LogDebug("Response:" + responsestr); await responseBody.CopyToAsync(originalBodyStream);
}
} }
// Extension method used to add the middleware to the HTTP request pipeline.
public static class LogReqResponseMiddlewareExtensions
{
public static IApplicationBuilder UseLogReqResponseMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<LogReqResponseMiddleware>();
}
}
然后在Startup类的Configure方法中添加下面一行代码,把自定义的中间添加到了HTTP请求的管道中。
app.UseLogReqResponseMiddleware();//记录http请求 输入、输出值;
我们在postman中模拟请求

控制台上打印的信息如下:

.NET Core 3.0 中间件 Middleware的更多相关文章
- [译]ASP.NET Core 2.0 中间件
问题 如何创建一个最简单的ASP.NET Core中间件? 答案 使用VS创建一个ASP.NET Core 2.0的空项目,注意Startup.cs中的Configure()方法: public vo ...
- .NET Core 3.0 部署在docker上运行
自从.NET Core3.0发布之后,写了几篇关于.NET Core 3.0的文章,有助于你快速入门.NET Core3.0. 本篇文章主要讲解如何一步步创建一个mvc项目,然后发布并部署在Docke ...
- [译]ASP.NET Core 2.0 系列文章目录
基础篇 [译]ASP.NET Core 2.0 中间件 [译]ASP.NET Core 2.0 带初始参数的中间件 [译]ASP.NET Core 2.0 依赖注入 [译]ASP.NET Core 2 ...
- [ASP.NET Core 2.0 前方速报]Core 2.0.3 已经支持引用第三方程序集了
发现问题 在将 FineUIMvc(支持ASP.NET MVC 5.2.3)升级到 ASP.NET Core 2.0 的过程中,我们发现一个奇怪的现象: 通过项目引用 FineUICore 工程一切正 ...
- ASP.NET Core 1.0中的管道-中间件模式
ASP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middleware)的方式注册在管道中.显而易见这样的设计非常松耦合 ...
- ASP.NET Core 1.0 静态文件、路由、自定义中间件、身份验证简介
概述 ASP.NET Core 1.0是ASP.NET的一个重要的重新设计. 例如,在ASP.NET Core中,使用Middleware编写请求管道. ASP.NET Core中间件对HttpCon ...
- Core 1.0中的管道-中间件模式
ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...
- 如何传递参数给ASP.NET Core的中间件(Middleware)
问题描述 当我们在ASP.NET Core中定义和使用中间件(Middleware)的时候,有什么好的办法可以给中间件传参数吗? 解决方案 在ASP.NET Core项目中添加一个POCO类来传递参数 ...
- ASP.NET Core -中间件(Middleware)使用
ASP.NET Core开发,开发并使用中间件(Middleware). 中间件是被组装成一个应用程序管道来处理请求和响应的软件组件. 每个组件选择是否传递给管道中的下一个组件的请求,并能之前和下一组 ...
随机推荐
- 死磕 java线程系列之线程模型
问题 (1)线程类型有哪些? (2)线程模型有哪些? (3)各语言使用的是哪种线程模型? 简介 在Java中,我们平时所说的并发编程.多线程.共享资源等概念都是与线程相关的,这里所说的线程实际上应该叫 ...
- java架构之路-(SpringMVC篇)SpringMVC主要流程源码解析(下)注解配置,统一错误处理和拦截器
我们上次大致说完了执行流程,也只是说了大致的过程,还有中间会出错的情况我们来处理一下. 统一异常处理 比如我们的运行时异常的500错误.我们来自定义一个类 package com.springmvcb ...
- BMap添加海量点数据,BMap.Point携带数据
在开发web项目的过程中使用到了百度地图,由于要在地图中画出很多点比较影响加载速度,查看官方文档,发现有提供加载海量点的功能BMap.PointCollection,用这个加快速度,但是官方文档中提供 ...
- Java 学习笔记之 线程脏读
线程脏读: 发生脏读的情况是在读取实例变量时,值已经被其他线程更改过了. public class DirtyReadVar { public String username = "A&qu ...
- 50个实用的jq代码段整理
个人博客: http://mcchen.club 1. 如何创建嵌套的过滤器: //允许你减少集合中的匹配元素的过滤器, //只剩下那些与给定的选择器匹配的部分.在这种情况下, //查 ...
- spring配置文件默认名称及位置,ContextLoaderListener监听器作用
spring在web.xml中的配置 由于spring需要启动容器才能为其他框架提供服务,而web应用程序的入口是由web服务器控制的,因此无法在main()方法中通过创建ClassPathXmlAp ...
- canvas实现平面迁徙图
前言 最近在做自己维护的一个可视化工具的时候,在添加基于echart的雷达图的时候,按照echart官网案例写完发现在自己项目中无法正常运行,排查了一番发现是我项目中echart的版本太低.找到问题原 ...
- B-微积分-sign(符号)函数
目录 sign(符号)函数 一.sign函数概述 二.python实现sign函数 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:h ...
- python编程基础之三十
时间模块: 时间戳:就是当前是键距离1970年1月1日0:0:0的秒数,后面还带小数,可以说是非常精确 时间的表示形式: a.以整数或者浮点数表示一个以秒为单位的时间间隔,这个时间的基础值1970.1 ...
- C# MQTT mqtt客户端,发布订阅消息
如果想用C#来和mqtt的服务器进行数据交互的话,有一个常见的选择,那就是 MQTTNET 地址如下:https://github.com/chkr1011/MQTTnet 那个库在最近几个版本升级的 ...