欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.net core webapi通过中间件获取请求和响应内容

程序员文章站 2022-05-15 10:30:20
本文主要根据中间件来实现对.net core webapi中产生的请求和响应数据进行获取并存入日志文件中; 这里不详细介绍日志文件的使用。你可以自己接入NLog,log4net,Exceptionless等 创建接口记录的中间件 在startup.cs中Configure方法中使用中间件 现在请求一 ......

本文主要根据中间件来实现对.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上,如下图

.net core webapi通过中间件获取请求和响应内容

 

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

.net core webapi通过中间件获取请求和响应内容

 

 

参考地址: (我只是在此基础上进行了一些小的改善)