lonix
lonix

Reputation: 20601

Where should static files middleware be in the ASP.NET Core pipeline?

I'm using ASP.NET Core 2.1. I thought the static files middleware should come before the mvc middleware - no need to run a request through mvc just to serve a css file for example.

So I have them in this order:

app.UseExceptionHandler(/*...*/)
app.UseHsts();
app.UseHttpsRedirection();
app.UseStatusCodePagesWithReExecute(/*...*/);
// and lastly:
app.UseStaticFiles();
app.UseMvc(/*...*/);

However when I turn on debug level logging, I notice that if a static file is missing, it runs through Microsoft.AspNetCore.Builder.RouterMiddleware and says Request did not match any routes, then runs my ErrorController and issues a 404 for that request.

So:

Upvotes: 8

Views: 3657

Answers (2)

Vitaliy
Vitaliy

Reputation: 100

is this the correct order for the pipeline?

Yes, it is.

However when I turn on debug level logging, I notice that if a static file is missing, it runs through Microsoft.AspNetCore.Builder.RouterMiddleware and says Request did not match any routes, then runs my ErrorController and issues a 404 for that request. Why?

First, your missing static file request is going through exception handler, HSTS, HTTPS redirection and StatusCodePagesWithReExecute middleware, but let's ignore them, because there is nothing interesting. Request just passes through them.

Then, it is processed by static files middleware. The middleware soon understands, that file is missing and just lets your request run to next middleware, which is MVC middlware.

MVC middleware looks through its route table and finds "catchAll" route and lets ErrorController process the request. That is the reason why missing files are processed by ErrorController.

P.S. I suppose you have "catchAll" route something like this:

app.UseMvc(routes =>
        {
            .... // your routes here

            routes.MapRoute("catchAll", "{*.}", new { controller = "Error", action = "Error404" }
        });

Upvotes: 3

Neville Nazerane
Neville Nazerane

Reputation: 7019

To get it lighter you can have a custom middleware something like this:

var avoidFolders = new string[] { "js", "css" };

app.Use(async (context, next) => {
    if (avoidFolders.Contains(context.Request.Path.Value.Trim('/')))
        context.Response.StatusCode = 404;
    else await next();
});

Although you will have to include every static folder in the array, it makes sure to directly return a 404 without proceeding to routing.

Upvotes: 1

Related Questions