Search code examples
c#asp.net-coremiddlewarerequest-pipeline

Why does ASP.NET Core return a 404 at the end of the Middleware Pipeline?


I wanted to find out how ASP.NET Core determines we have reached the end of the middleware pipeline and starts sending the response back. This is the code that handles it (from the GitHub repository):

public RequestDelegate Build()
{
    RequestDelegate app = context =>
    {
        /*
        Some code omitted for clarity
        */
        context.Response.StatusCode = 404;
        return Task.CompletedTask;
    };

    foreach (var component in _components.Reverse())
    {
        app = component(app);
    }

    return app;
}

My question is this: What does the line context.Response.StatusCode = 404; do? Why is it even there? Shouldn't it be a 200 ("OK")? Where is the code that changes this default value so that we don't get a "404 Not Found" error on every request?


Solution

  • What does the line context.Response.StatusCode = 404; do? Why is it even there?

    This call ends up being run as the last component within the middleware pipeline. If the incoming request makes it all the way to the end of the pipeline that you configured, this code will run. It's there to ensure that a 404 is returned when a request isn't handled by your application.

    Shouldn't it be a 200 ("OK")?

    No, a HTTP 200 OK response isn't appropriate for this. That indicates that the request was handled successfully, but in fact it wasn't handled at all, because logic for processing this particular request was not found (HTTP 404 NotFound).

    Where is the code that changes this default value so that we don't get a "404 Not Found" error on every request?

    The middleware pipeline supports the concept of short-circuiting (see the docs). Briefly, this means a middleware component decides whether or not to execute the next middleware component in the pipeline. Imagine the following, simplified pipeline setup:

    app.UseStaticFiles();
    
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
    

    In this pipeline, both the static-files and the endpoints middleware may short-circuit the pipeline. If the static-files middleware is able to process the request, it usually sets the status-code to HTTP 200 and returns the file. If the endpoints middleware finds a matching controller/action, it could do one of many things, but usually it will set a success status code such as HTTP 200.

    Only if neither the static-files middleware nor the endpoints middleware manages to handle the request, the line called out (context.Response.StatusCode = 404;) will run as a sort of fallback.