欢迎光临
我们一直在努力

.net core 3.0 通过中间件拦截或获取Request.Body、Response的返回值

这篇文章我们讲解一下.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();
            });
        }
    }
}

 

赞(0)
未经允许不得转载:自游互动 » .net core 3.0 通过中间件拦截或获取Request.Body、Response的返回值
分享到: 更多 (0)

自由技术,自由自在

项目合作联系我们