Home > Software design >  Middleware works in program.cs, but not when moved to it's own class
Middleware works in program.cs, but not when moved to it's own class

Time:04-03

I'm using asp.net core 6, in my program.cs I have the following middleware, which is used to redirect the user when the statuscode is 404.

app.Use(async (ctx, next) =>
{
    await next();

    if (ctx.Response.StatusCode == 404 && !ctx.Response.HasStarted)
    {
        string originalPath = ctx.Request.Path.Value;
        ctx.Items["originalPath"] = originalPath;
        ctx.Request.Path = "/error/NotFound404";
        await next();
    }
});

This all works fine, but I want to clean up my program.cs a bit, so I decided to put this code in it's own class like this:

public class NotFoundMiddleware
{
    private readonly RequestDelegate _next;
    public NotFoundMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    public async Task InvokeAsync(HttpContext httpContext)
    {

        if (httpContext.Response.StatusCode == 404 && !httpContext.Response.HasStarted)
        {
            string originalPath = httpContext.Request.Path.Value;
            httpContext.Items["originalPath"] = originalPath;
            httpContext.Request.Path = "/error/NotFound404";
        }
        
        await _next(httpContext);
    }
}

public static class NotFoundMiddlewareExtensions
{
    public static IApplicationBuilder CheckNotFound(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<NotFoundMiddleware>();
    }
}

And in my program.cs

app.CheckNotFound(); // on the same place the upp.Use... was before.

But then it doesn't work anymore.

I went through my code using breakpoints. and the InvokeAsync gets called on each request, The problem is that the httpContext.Response.StatusCode always returns 200.

CodePudding user response:

Your inline middleware calls next before testing the return value. The class only calls next after.

  • Related