田敏
返回博客列表
ASP.NET Core

🧰 ASP.NET Core 中间件模板代码速查表

田敏
2025-10-312 分钟阅读
.NETC#Backend

🧰 ASP.NET Core 中间件模板代码速查表

🚀 三个最常见的中间件模板:异常处理、认证、日志记录。 每个模板都遵循 标准委托式写法(带 InvokeAsync),可直接复制使用。


🧩 一、全局异常处理中间件模板

📘 用途:统一捕获异常,返回统一格式的错误响应,避免系统崩溃。

public class ExceptionHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ExceptionHandlingMiddleware> _logger;

    public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context); // 调用下一个中间件
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unhandled exception occurred.");

            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = "application/json";

            var result = JsonSerializer.Serialize(new
            {
                code = 500,
                message = "服务器内部错误,请联系管理员",
                detail = ex.Message
            });

            await context.Response.WriteAsync(result);
        }
    }
}

注册方式:

app.UseMiddleware<ExceptionHandlingMiddleware>();

🔐 二、Basic Auth 认证中间件模板(保护 Swagger 或管理页)

📘 用途:对指定路径(如 /swagger)进行基本用户名密码认证。

public class BasicAuthMiddleware
{
    private readonly RequestDelegate _next;
    private readonly string _username;
    private readonly string _password;

    public BasicAuthMiddleware(RequestDelegate next, IConfiguration config)
    {
        _next = next;
        _username = config["Auth:Username"];
        _password = config["Auth:Password"];
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Path.StartsWithSegments("/swagger"))
        {
            await _next(context);
            return;
        }

        if (!context.Request.Headers.TryGetValue("Authorization", out var authHeader))
        {
            Challenge(context);
            return;
        }

        var header = authHeader.ToString();
        const string prefix = "Basic ";

        if (!header.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
        {
            Challenge(context);
            return;
        }

        var encoded = header.Substring(prefix.Length).Trim();
        string decoded;
        try
        {
            var bytes = Convert.FromBase64String(encoded);
            decoded = Encoding.UTF8.GetString(bytes);
        }
        catch
        {
            Challenge(context);
            return;
        }

        var parts = decoded.Split(':', 2);
        if (parts.Length != 2 || parts[0] != _username || parts[1] != _password)
        {
            Challenge(context);
            return;
        }

        await _next(context);
    }

    private static void Challenge(HttpContext context)
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        context.Response.Headers["WWW-Authenticate"] = @"Basic realm=""Restricted Area""";
    }
}

注册方式:

app.UseMiddleware<BasicAuthMiddleware>();

配置示例(appsettings.json):

"Auth": {
  "Username": "admin",
  "Password": "123456"
}

🧾 三、请求日志中间件模板

📘 用途:记录请求和响应时间、路径、状态码,用于性能与审计分析。

public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<RequestLoggingMiddleware> _logger;

    public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var start = DateTime.UtcNow;
        var request = context.Request;

        _logger.LogInformation("➡️  {Method} {Path} started at {Time}",
            request.Method, request.Path, start);

        await _next(context);

        var elapsed = DateTime.UtcNow - start;
        _logger.LogInformation("⬅️  {Method} {Path} completed with {StatusCode} in {Elapsed} ms",
            request.Method, request.Path, context.Response.StatusCode, elapsed.TotalMilliseconds);
    }
}

注册方式:

app.UseMiddleware<RequestLoggingMiddleware>();

📎 四、可选顺序建议(中间件链)

Program.cs 中中间件的注册顺序非常重要:

app.UseMiddleware<ExceptionHandlingMiddleware>();  // 全局异常(最靠前)
app.UseMiddleware<RequestLoggingMiddleware>();     // 日志记录
app.UseMiddleware<BasicAuthMiddleware>();          // Basic 认证(针对 Swagger)
app.UseRouting();
app.UseAuthorization();
app.MapControllers();

🧠 五、快速记忆口诀

🧱 中间件三步走: ① 构造函数注入 RequestDelegate next ② 写 InvokeAsync(HttpContext)await _next(context) 放行下一个环节

版权协议:MIT返回列表