根据请求上下文动态设置静态文件存储目录
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据请求上下文动态设置静态文件存储目录相关的知识,希望对你有一定的参考价值。
前言
上次,我们实现了根据 subpath
特定格式《动态设置静态文件存储目录》。
例如:
subpath | 静态文件路径 |
---|---|
/userAId/1.jpg | c:\\abc\\userAId\\1.jpg |
/userBId/1.jpg | d:\\xyz\\123\\userBId\\1.jpg |
但是,如果 subpath
不能有这种特定格式,只能用通用格式,比如https://<hostname>/StaticFiles/images/1.jpg
。
怎么实现?
思路
请求上下文肯定包含了信息能够区分出用户,比如 Session/Cookie、二级域名等,可以通过它来反向映射出静态文件路径。
例如:
二级域名 | 静态文件路径 |
---|---|
a.mycompany.com | c:\\abc\\ |
b.mycompany.com | d:\\xyz\\123 |
在 IFileProvider
接口实现中,我们获取不到当前请求上下文,但是中间件可以。
查看 UseStaticFiles
源代码,它使用的是 StaticFileMiddleware
中间件:
public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app, StaticFileOptions options)
...
return app.UseMiddleware<StaticFileMiddleware>(Options.Create(options));
查看 StaticFileMiddleware
源代码[1],它的关键实现是这个TryServeStaticFile
方法:
public class StaticFileMiddleware
...
private Task TryServeStaticFile(HttpContext context, string? contentType, PathString subPath)
var fileContext = new StaticFileContext(context, _options, _logger,
_fileProvider, contentType, subPath);
if (!fileContext.LookupFileInfo())
_logger.FileNotFound(fileContext.SubPath);
else
// If we get here, we can try to serve the file
return fileContext.ServeStaticFile(context, _next);
return _next(context);
具体如何获取静态文件是依赖_fileProvider
,因此,我们只需要替换 _fileProvider
,换成根据请求上下文获取对应 PhysicalFileProvider
的方法即可。
实现
创建 MyiostaticFileMiddleware
,复制 StaticFileMiddleware
的原始代码,仅仅修改 TryServeStaticFile
方法:
public class MyIOStaticFileMiddleware
...
private Task TryServeStaticFile(HttpContext context, string? contentType, PathString subPath)
var fileContext = new StaticFileContext(context, _options, _logger,
GetPhysicalFileProvider(context), contentType, subPath);
...
return _next(context);
然后根据 context
获取对应的 PhysicalFileProvider
进行处理:
private IFileProvider GetPhysicalFileProvider(HttpContext context)
//实际可从数据库获取
if (context.Request.Host.Host.StartsWith("a.mycompany.com"))
return new PhysicalFileProvider(@"c:\\abc");
if (context.Request.Host.Host.StartsWith("b.mycompany.com"))
return new PhysicalFileProvider(@"d:\\xyz\\123");
...
使用
按如下方式配置静态文件中间件:
app.UseMiddleware<MyIOStaticFileMiddleware>();
运行效果如图:
结论
今天,我们通过自定义 StaticFileMiddleware
,实现了根据请求上下文动态设置静态文件存储目录。
想了解更多内容,请关注我的个人公众号”My IO“
参考资料
[1]
源代码: https://github.com/dotnet/aspnetcore/blob/main/src/Middleware/StaticFiles/src/StaticFileMiddleware.cs
以上是关于根据请求上下文动态设置静态文件存储目录的主要内容,如果未能解决你的问题,请参考以下文章