我正在编写一些中间件来解析给定请求 URL 的子域以确定网站主题。我想忽略静态文件请求以减少不必要的数据库查找,我想知道是否有更干净的方法来做到这一点。
这是我迄今为止尝试过的:
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;
}
}
这是我将其添加到 Startup.cs 的位置:
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseDomainWhitelisting();
感觉好像应该有一种更干净的方法来检测要忽略哪些请求,或者也许我错过了一些东西?
您可以根据请求使用条件中间件。 比如:
app.UseMiddlewareOne();
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), appBuilder =>
{
appBuilder.UseMiddlewareTwo();
});
app.UseMiddlewareThree();
来源: https://www.devtrends.co.uk/blog/conditional-middleware-based-on-request-in-asp.net-core
这是一个很老的问题,但当我遇到类似的问题时我就想到了这个问题, 我可以通过检查请求是否以扩展名结束来解决问题并确定静态文件请求。
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)
你不需要。
如果请求最终提供静态文件,则在调用
UseStaticFiles
之后注册的任何中间件都不会执行。
我刚刚在 Windows 和 Linux 上的 IIS 和 Kestrel 托管下的 .NET 6 和 7 上验证了此行为。
这可能是因为静态文件中间件从不调用
_next(context)
委托,从而中止整个管道。这被称为终端中间件,因为它短路请求。我希望 MS 文档在某处提到它,但我们总是可以查看源代码......
啊啊-是的,正如我所想,源代码证实了这一点:https://source.dot.net/#Microsoft.AspNetCore.StaticFiles/StaticFileMiddleware.cs,79
附注换句话说,要解决OP的问题 - 只需确保在执行域逻辑中间件之前调用
UseStaticFiles
。还要确保该文件确实存在。如果没有 - 应用程序将继续到下一个中间件。