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();
}
}
我需要对我的 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();
}
}