界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
效率与协作 · SKILL.md

aspnet-middleware

aspnet-middleware

【效率与协作】ASP.NET Core custom middleware, pipeline order, exception handling middleware, and request/response manipulation. USE WHEN: user mentions "middleware", "request pipeline", "exception middleware", "ASP.NET middleware", "UseMiddleware", "pipeline order" DO NOT USE FOR: Express middleware - use `express`, NestJS middleware - use `nestjs`

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: aspnet-middleware description: | ASP.NET Core custom middleware, pipeline order, exception handling middleware, and request/response manipulation.

USE WHEN: user mentions "middleware", "request pipeline", "exception middleware", "ASP.NET middleware", "UseMiddleware", "pipeline order"

DO NOT USE FOR: Express middleware - use express, NestJS middleware - use nestjs allowed-tools: Read, Grep, Glob, Write, Edit

ASP.NET Core Middleware - Quick Reference

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: aspnet-core, topic: middleware for comprehensive documentation.

Pipeline Order

Request → Exception Handler → HSTS → HTTPS Redirect → Static Files
→ CORS → Authentication → Authorization → Custom Middleware → Endpoint
var app = builder.Build();

// 1. Exception handling (first to catch all)
app.UseExceptionHandler("/error");
app.UseHsts();

// 2. HTTPS and static files
app.UseHttpsRedirection();
app.UseStaticFiles();

// 3. Routing
app.UseRouting();

// 4. CORS (before auth)
app.UseCors();

// 5. Auth
app.UseAuthentication();
app.UseAuthorization();

// 6. Custom middleware
app.UseMiddleware<RequestLoggingMiddleware>();

// 7. Endpoints
app.MapControllers();

Custom Middleware (Convention-based)

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 sw = Stopwatch.StartNew();

        _logger.LogInformation("Request {Method} {Path}", context.Request.Method, context.Request.Path);

        await _next(context);

        sw.Stop();
        _logger.LogInformation("Response {StatusCode} in {Elapsed}ms",
            context.Response.StatusCode, sw.ElapsedMilliseconds);
    }
}

// Register
app.UseMiddleware<RequestLoggingMiddleware>();

Exception Handling Middleware

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

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

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (NotFoundException ex)
        {
            context.Response.StatusCode = StatusCodes.Status404NotFound;
            await context.Response.WriteAsJsonAsync(new { error = ex.Message });
        }
        catch (ValidationException ex)
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
            await context.Response.WriteAsJsonAsync(new { errors = ex.Errors });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unhandled exception");
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            await context.Response.WriteAsJsonAsync(new { error = "An unexpected error occurred" });
        }
    }
}

Inline Middleware

// Simple Use
app.Use(async (context, next) =>
{
    context.Response.Headers.Append("X-Request-Id", Guid.NewGuid().ToString());
    await next(context);
});

// Terminal middleware (does not call next)
app.Map("/health", app => app.Run(async context =>
{
    await context.Response.WriteAsync("OK");
}));

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Wrong middleware orderAuth bypassed, CORS failsFollow documented order
Exception handler not firstMisses early errorsPlace at start of pipeline
Reading body without bufferingStream consumed onceEnable EnableBuffering()
Blocking calls in middlewareThread starvationUse async Task InvokeAsync

Quick Troubleshooting

IssueLikely CauseSolution
CORS not workingWrong orderPlace UseCors() before UseAuth
Middleware not executingRegistered after endpointsRegister before MapControllers()
Body empty in middlewareAlready read by bindingUse EnableBuffering()
Static files not servedWrong orderPlace UseStaticFiles() early
我的收藏