zoukankan      html  css  js  c++  java
  • .net core webapi通过中间件获取请求和响应内容

    本文主要根据中间件来实现对.net core webapi中产生的请求和响应数据进行获取并存入日志文件中;

    这里不详细介绍日志文件的使用。你可以自己接入NLog,log4net,Exceptionless等

    创建接口记录的中间件

    using Microliu.Core.Loggers;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.Internal;
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Ptibro.Partner.API.Extensions
    {
    
        public class RequestResponseLoggingMiddleware
        {
            private readonly RequestDelegate _next;
            private readonly ILogger _logger;
    
            private SortedDictionary<string, object> _data;
            private Stopwatch _stopwatch;
    
    
            public RequestResponseLoggingMiddleware(RequestDelegate next, ILogger logger)
            {
                _next = next;
                _logger = logger;
                _stopwatch = new Stopwatch();
            }
    
            public async Task Invoke(HttpContext context)
            {
                _stopwatch.Restart();
                _data = new SortedDictionary<string, object>();
    
                HttpRequest request = context.Request;
                _data.Add("request.url", request.Path.ToString());
                _data.Add("request.headers", request.Headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value.ToList())));
                _data.Add("request.method", request.Method);
                _data.Add("request.executeStartTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
    
                // 获取请求body内容
                if (request.Method.ToLower().Equals("post"))
                {
                    // 启用倒带功能,就可以让 Request.Body 可以再次读取
                    request.EnableRewind();
    
                    Stream stream = request.Body;
                    byte[] buffer = new byte[request.ContentLength.Value];
                    stream.Read(buffer, 0, buffer.Length);
                    _data.Add("request.body", Encoding.UTF8.GetString(buffer));
    
                    request.Body.Position = 0;
                }
                else if (request.Method.ToLower().Equals("get"))
                {
                    _data.Add("request.body", request.QueryString.Value);
                }
    
                // 获取Response.Body内容
                var originalBodyStream = context.Response.Body;
    
                using (var responseBody = new MemoryStream())
                {
                    context.Response.Body = responseBody;
    
                    await _next(context);
    
                    _data.Add("response.body", await GetResponse(context.Response));
                    _data.Add("response.executeEndTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
    
                    await responseBody.CopyToAsync(originalBodyStream);
                }
    
                // 响应完成记录时间和存入日志
                context.Response.OnCompleted(() =>
                {
                    _stopwatch.Stop();
                    _data.Add("elaspedTime", _stopwatch.ElapsedMilliseconds + "ms");
                    var json = JsonConvert.SerializeObject(_data);
                    _logger.Debug(json, "api", request.Method.ToUpper());
                    return Task.CompletedTask;
                });
    
            }
    
            /// <summary>
            /// 获取响应内容
            /// </summary>
            /// <param name="response"></param>
            /// <returns></returns>
            public async Task<string> GetResponse(HttpResponse response)
            {
                response.Body.Seek(0, SeekOrigin.Begin);
                var text = await new StreamReader(response.Body).ReadToEndAsync();
                response.Body.Seek(0, SeekOrigin.Begin);
                return text;
            }
        }
    
        /// <summary>
        /// 扩展中间件
        /// </summary>
        public static class RequestResponseLoggingMiddlewareExtensions
        {
            public static IApplicationBuilder UseRequestResponseLogging(this IApplicationBuilder app)
            {
                return app.UseMiddleware<RequestResponseLoggingMiddleware>();
            }
        }
    
    }

    在startup.cs中Configure方法中使用中间件

            public void Configure(IApplicationBuilder app, IHostingEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
    
                app.UseErrorHandling();// 全局异常尽量放上面
                ...
                app.UseRequestResponseLogging();
                ...
                app.UseExceptionless(Configuration);
                app.UseMvc();
            }

    现在请求一次看一下记录的效果:我的日志存在exceptionless上,如下图

     解析json,记录的数据如下:

    参考地址:https://www.cnblogs.com/wybin6412/p/10944077.html (我只是在此基础上进行了一些小的改善)

  • 相关阅读:
    前端 JS,localStorage/sessionStorage、cookie 及 url 等实现前台数据共享、传输
    webpack 利用Code Splitting 分批打包、按需下载
    React项目之BrowserRouter路由方式之-------生产环境404问题
    React生产环境打包&&后台环境运行(有跨域+无跨域)
    React前台改用HashRouter并解决两个问题
    React路由基础
    React前台404组件页面+路由控制重定向
    react调用方法
    JavaScript 数组遍历方法的对比
    数据可视化相关库说明
  • 原文地址:https://www.cnblogs.com/chinaliu/p/11532492.html
Copyright © 2011-2022 走看看