这篇文章我们讲解一下.net core3.0如何拦截或获取Request.Body和Response的返回值
在项目中我们经常可能会遇到需拦截Request.Body和Response的返回值的时候 比如授权、请求日志、调试时
之前我写过一个通过filter过滤器的方式实现的文章 。.net core 3.0 在滤过器FilterAttribute中获取Request.Body的值
今天我在讲一下能过中间件方式实现的例子
第一步、创建中间件文件,并写相关代码
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace CountingCardService { public class ResultMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public ResultMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger<ResultMiddleware>(); } public async Task InvokeAsync(HttpContext context) { try { MemoryStream ms1 = null; StreamWriter writer = null; HttpRequest request = context.Request; // 获取请求body内容 if (request.Method.ToLower().Equals("post")) { // 启用倒带功能,就可以让 Request.Body 可以再次读取 request.EnableBuffering(); Stream stream = request.Body; //获取到body值 string bodyAsText = await new StreamReader(request.Body).ReadToEndAsync(); //修改body值 bodyAsText = Regex.Replace(bodyAsText, "(\":\")([0-9]{16,19})(\",)", "\":$2,"); //放到流中回填回去 ms1 = new MemoryStream(); writer = new StreamWriter(ms1); writer.Write(bodyAsText); writer.Flush(); request.Body = ms1; request.Body.Position = 0; } //获取到Response.body内容 using (var ms = new MemoryStream()) { var orgBodyStream = context.Response.Body; context.Response.Body = ms; //context.Response.ContentType = "multipart/form-data"; //执行controller中正常逻辑代码 await _next(context); using (var sr = new StreamReader(ms)) { ms.Seek(0, SeekOrigin.Begin); //得到Action的返回值 var responseJsonResult = sr.ReadToEnd(); ms.Seek(0, SeekOrigin.Begin); //如下代码若不注释则会显示Action的返回值 这里做了注释 则清空Action传过来的值 // await ms.CopyToAsync(orgBodyStream); responseJsonResult = Regex.Replace(responseJsonResult, "(\":)([0-9]{16,})(,)", "$1\"$2\"$3"); var alterResult = responseJsonResult; context.Response.Body = orgBodyStream; //显示修改后的数据 await context.Response.WriteAsync(alterResult, Encoding.UTF8); } } if (writer != null) { writer.Close(); writer.Dispose(); } if (ms1 != null) { ms1.Close(); ms1.Dispose(); } } catch (Exception ex) { throw ex; } } } }
第二步 修改Startup.cs文件
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CountingCardServiceBLL; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace CountingCardService { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); //添加我们刚刚的中间件 app.UseResult(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }