Reputation: 2642
I'm writing some middleware to parse the sub-domain of a given request URL to determine the website theme. I want to ignore static file requests in order to reduce unnecessary database lookups, and I'm wondering if there's a cleaner way to do it.
This is what I've tried so far:
var staticFileExtensions = new List<string> { ".css", ".js", ".png", ".ico" };
if (staticFileExtensions.Any(x => httpContext.Request.Path.Value.EndsWith(x)))
{
await _next(httpContext);
}
else
{
var hostParts = httpContext.Request.Host.Host.Split('.').ToList();
if (httpContext.Request.Path.StartsWithSegments(new PathString("/healthcheck"))
|| (hostParts.Count == 6 && _whitelistedDomains.Contains(hostParts[0])))
{
httpContext.Items.Add("account", hostParts[0]);
await _next(httpContext);
}
else
{
httpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
}
}
This is where I've added it to Startup.cs:
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseDomainWhitelisting();
It feels as though there should be a cleaner way to detect which requests to ignore, or maybe I'm missing something?
Upvotes: 12
Views: 3628
Reputation: 49
Maybe check if httpContext.GetEndpoint()
is null or not.
Under tests yet in my projects, but looks good.
Upvotes: 0
Reputation: 60566
You don't need to.
Any middleware that is registered AFTER the call to UseStaticFiles
will not execute, if the request ended up serving a static file.
I just verified this behavior on .NET 6 and 7 under both IIS and Kestrel hosting on both Windows and Linux.
That's probably because the static-files middleware never calls _next(context)
delegate, thus aborting the whole pipeline. This is called terminal middleware because it short circuits a request. I wish MS docs mentioned it somewhere, but we can always look at the source codes...
Aaaah-nd yep, just as I thought, source code confirms this: https://source.dot.net/#Microsoft.AspNetCore.StaticFiles/StaticFileMiddleware.cs,79
P.S. In other words, to solve the OP's problem - just make sure you call UseStaticFiles
before executing your domain logic middleware. Also make sure the file actually exists. If not - the app will proceed to next middleware.
Upvotes: 9
Reputation: 628
This is quite old question but I cam to it when I had similar problem, I could solve the issue and determine static files request by checking if request is ended with extension.
if(string.IsNullOrEmpty(System.IO.Path.GetExtension(httpContext.Request.Path)))
//this is normal request
else
//this can be a file as it ends with some extension (ex*.png)
Upvotes: 6
Reputation: 969
You can use conditional middleware based on request. Something like:
app.UseMiddlewareOne();
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
appBuilder.UseMiddlewareTwo();
});
app.UseMiddlewareThree();
Source: https://www.devtrends.co.uk/blog/conditional-middleware-based-on-request-in-asp.net-core
Upvotes: 9