C# .NET6 中间件 获取请求和响应信息

复制代码
/// <summary>
/// HTTP中间件
/// </summary>
public class HttpMiddleware
{
    /// <summary>
    /// 请求委托
    /// </summary>
    private readonly RequestDelegate _next;
    /// <summary>
    /// 日志
    /// </summary>
    private readonly ILogger _logger;
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="next"></param>
    /// <param name="logger"></param>
    public HttpMiddleware(RequestDelegate next, ILogger<HttpMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }
    /// <summary>
    /// 异步调用
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    public async Task InvokeAsync(HttpContext context)
    {
        #region Request信息
        // 判断请求类型
        if (context.Request.Method == "GET")
        {
            // 取得请求数据
            string? queryString = context.Request.QueryString.Value;
            // 日志
            string outMsg = string.Format("Method: {0}, Host: {1}, Path: {2}, QueryString: {3}",
                context.Request.Method,
                context.Request.Host,
                context.Request.Path,
                queryString);
            // 输出
            _logger.LogInformation(outMsg);
        }
        else
        {
            // 开启数据缓存
            context.Request.EnableBuffering();
            using (MemoryStream memoryStream = new())
            {
                // 复制Body数据到缓存
                await context.Request.Body.CopyToAsync(memoryStream);
                context.Request.Body.Position = 0;
                using (StreamReader streamReader = new(memoryStream))
                {
                    // 读取Body数据
                    string? body = await streamReader.ReadToEndAsync();
                    // 日志
                    string outMsg = string.Format("Method: {0}, Host: {1}, Path: {2}, Request body: {3}",
                        context.Request.Method,
                        context.Request.Host,
                        context.Request.Path,
                        body);
                    // 输出
                    _logger.LogInformation(outMsg);
                }
            }
        }
        #endregion
        #region Response信息
        // 原Body缓存
        Stream originalBody = context.Response.Body;
        try
        {
            // 新Body缓存
            using (MemoryStream memoryStream = new())
            {
                // Body赋值为新Body缓存
                context.Response.Body = memoryStream;
                // 向下执行(等待返回)
                await _next.Invoke(context);
                // 原Body缓存赋值为新Body缓存
                memoryStream.Position = 0;
                await memoryStream.CopyToAsync(originalBody);
                using (StreamReader streamReader = new(memoryStream))
                {
                    // 读取Body数据
                    memoryStream.Position = 0;
                    string body = await streamReader.ReadToEndAsync();
                    // 日志
                    string outMsg = string.Format("Method: {0}, Host: {1}, Path: {2}, Response body: {3}",
                        context.Request.Method,
                        context.Request.Host,
                        context.Request.Path,
                        body);
                    // 输出
                    _logger.LogInformation(outMsg);
                }
            }
        }
        finally
        {
            // Body重新赋值为原始Body缓存
            context.Response.Body = originalBody;
        }
        #endregion
    }
}
复制代码

 

posted @   Mr_Xul  阅读(1007)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示