ASP.NET Core基础之中间件(二)-自定义中间件

阅读本文你的收获:

  1. 学习如何自定义中间件
  2. 学会封装一个日志记录中间件

本文主要分享的是如何自定义中间件,如果想要了解中间件的基本概念,请看ASP.NET Core基础之中间件(一)

一、场景描述

内置的中间件可以对请求和响应进行一些处理,但是无法知道请求花了多少时间,当发生异常时也无法把错误信息进行捕获并记录到日志文件文件中。当内置中间件无法满足我们的需求时,就需要自己动手DIY一个自定义中间件了。
为了满足以上的需求,我们一起来自定义一个请求日志中间件,它有以下的功能:

  1. 可以记录请求的处理所消耗的时间
  2. 当请求发生异常的时候,可以捕获并记录到日志里面

二、实现请求日志中间件

编写自定义中间件的流程

中间件流程以下一步步带你来实现自定义中间件,开发环境:

  • 平台版本是:.NET6
  • 开发框架:ASP.NET Core WebApi
  • 开发工具:Visual Studio2022

1. 定义请求日志中间件类

注意点
(1) 出于规范性考虑,自定义中间件类的名称以Middleware结尾,如RequestLogMiddleware是我定义的请求日志中间件类。

(2) 写一个中间件类,该类必须满足以下要求:

  • 类的公共构造函数至少有一个 RequestDelegate 类型的参数,其它的参数根据情况自行决定要不要加
  • 类中必须有一个名为Invoke或InvokeAsync的公共方法,此方法的第一个参数必须是 HttpContext 类型,该方法返回类型为Task
using Microsoft.AspNetCore.Http;  //
using Microsoft.Extensions.Logging; //日志记录
using System.Diagnostics;   //秒表

/// <summary>
/// 请求日志中间件(无需继承任何基类)
/// </summary>
public class RequestLogMiddleware
{
    //下一个请求委托
    private readonly RequestDelegate _next;
    //通过构造函数完成日志工具对象的注入
    private readonly ILogger<RequestLogMiddleware> _logger;  
    
    /// <summary>
    /// 构造方法
    /// </summary>
    /// <param name="next">请求委托</param>
    /// <param name="logger">日志工具对象</param>
    /// <returns></returns>
    public RequestLogMiddleware(RequestDelegate next, ILogger<RequestLogMiddleware> logger)
    {
        _next = next;
        _logger = logger; 
    }

    /// <summary>
    /// 公开方法
    /// </summary>
    /// <param name="context">Http请求上下文</param>
    /// <returns></returns>
        public async Task InvokeAsync(HttpContext context)
        {
            string requestUrl = context.Request.Path;
            try
            {
                //实例化一个秒表对象,用于记录执行前后的时间
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();

                await _next(context); //继续调用下一个请求委托
                
                stopwatch.Stop();
               
                _logger.LogInformation($"请求{requestUrl},消耗了{stopwatch.ElapsedMilliseconds}毫秒");
            }
            catch (Exception ex)
            {

                //异常日志记录到文件
                _logger.LogError($"请求异常:{requestUrl},错误信息:{ex.Message}");
            }
        }
}

代码说明:

  • 可以看到在代码中await _next(context);的前后加了秒表计时的功能,这样我们就能知道请求耗时了。
  • 另外用try…catch进行异常捕获,这样当请求处理发生异常时,就可以将错误信息记录到日志中。
  • 本代码中记录的日志信息较为简单是输出到 控制台界面,如果要记录到文件中,还需要结合NLog、Log4Net这样的日志组件。

2. 封装扩展方法

写一个扩展方法 将以上中间件公开给使用者:

using Microsoft.AspNetCore.Builder; //IApplicationBuilder所在的命名空间

/// <summary>
/// 以下扩展方法,将以上中间件公开给使用者
/// </summary>
public static class RequestLogMiddlewareExt
{
    public static IApplicationBuilder UseRequestLogMiddleware(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<RequestLogMiddleware>();
    }
}

3. 在中间件管道中,使用RequestLog中间件

使用自定义日志中间件

三、测试自定义中间件

在Swagger中的请求某个api,可以在控制台窗口中,看到请求的耗时信息。
测试结果

总结

当内置的中间件无法满足你需求的时候,我们可以按照以上的流程来自定义中间件,实现对请求或响应的特殊处理场景,如记录日志的中间件、处理异常的中间件、防止SQL注入的中间件等。需要重申的是,中间件类,必须满足以下条件:

  • 类的公共构造函数至少有一个 RequestDelegate 类型的参数,其它的参数根据情况自行决定要不要加
  • 类中必须有一个名为Invoke或InvokeAsync的公共方法,此方法的第一个参数必须是 HttpContext 类型,该方法返回类型为Task

本次分享就这么多,希望对你有帮助。关于如何记录更详细的日志信息,我将在后期的博文中分享,欢迎评论+关注。

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

采石之人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值