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;   //秒表

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

    /// 
    /// 公开方法
    /// 
    /// Http请求上下文
    /// 
        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所在的命名空间

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

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

ASP.NET Core基础之中间件(二)-自定义中间件_第1张图片

三、测试自定义中间件

在Swagger中的请求某个api,可以在控制台窗口中,看到请求的耗时信息。
ASP.NET Core基础之中间件(二)-自定义中间件_第2张图片

总结

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

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

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

你可能感兴趣的:(#,ASP.NET,Core,asp.net,中间件,后端,.netcore)