ASP.NET Core 中的任何 FileProvider 都可以按文件夹而不是参数提供版本控制文件?

Any FileProvider in ASP.NET Core to provide versioned files by folder instead of parameter?

我需要对我的 Javacript 文件进行版本控制(用于清除缓存),但无法使用 asp-append-version,因为脚本文件来自 Javascript import:

import * as Foo from './foo.js'

因此,我计划有一个 FileProvider 可以为带有 /js/v1.0/app.js 之类请求的文件提供服务(因此 foo.js 将从 /js/v1.0/foo.js 提供服务)。可以服务/v1.0/js/main.js,只要保持相对路径即可。

我试过这个:

        app.UseStaticFiles(new StaticFileOptions()
        {
            RequestPath = "/v*",
        });
        app.UseStaticFiles();

但是不行,RequestPath不支持通配符

有没有办法在没有自定义中间件的情况下做到这一点?在我看来,一个 FileProvider 中间件对于这个来说太过分了。这是我目前的临时解决方案:

    public static IApplicationBuilder UseVersionedScripts(this IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            if (context.Request.Path.HasValue &&
                context.Request.Path.Value.ToLower().StartsWith("/js/v"))
            {
                var filePath = context.Request.Path.Value.Split('/');


                // Write the file to response and return if file exist
            }

            await next.Invoke();
        });

        return app;
    }

编辑:我认为在我的情况下,如果不支持 FileProvider,Controller Action 可能比中间件更好,因为 PhysicalFile 方法可以处理写入。

我制作了一个可重复使用的 FileProvider "transforms"(删除)版本路径:https://github.com/BibliTech/VersionedFileProvider

var versionedFileProvider = new VersionedFileProvider(env.WebRootFileProvider);
app.UseStaticFiles(new StaticFileOptions()
{
    FileProvider = versionedFileProvider,
});

旧答案:

最后我用一个动作来提供文件:

[ApiController]
public class FileController : ControllerBase
{

    IHostEnvironment env;
    public FileController(IHostEnvironment env)
    {
        this.env = env;
    }

    [HttpGet, Route("/js/{version}/{**path}")]
    public IActionResult JavascriptFile(string version, string path)
    {
        var filePath = Path.Combine(
            env.ContentRootPath,
            @"wwwroot\js",
            path);

        if (System.IO.File.Exists(filePath))
        {
            return this.PhysicalFile(filePath, "application/javascript");
        }

        return this.NotFound();
    }

}