前言
文章名字有点绕口,举例说明一下:
多用户使用同一个网站上传文件,但是因为一些原因,文件需要存储到服务器的不同目录下。
比如用户 A 对应 c:\abc
,用户 B 对应 d:\xyz\123
。
并且,文件需要以静态文件方式提供访问。
由于每个用户的静态文件存储目录不同,这就需要根据用户当前请求动态确定存储目录。
怎么实现?
思路默认情况下,静态文件存储在项目的 Web 根目录中。默认目录为 {content root}/wwwroot
。
如果要使用其他目录,可以按如下方式配置静态文件中间件:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(@"c:\abc")
});
查看 FileProvider
属性,它是 IFileProvider
接口的实例:
public interface IFileProvider
{
IFileInfo GetFileInfo(string subpath);
...
}
其中,subpath
是相对于 Web 根目录的标识文件的相对路径:
https:///StaticFiles/images/red-rose.jpg
//subpath
/StaticFiles/images/red-rose.jpg
//静态文件路径
c:\abc\StaticFiles\images\red-rose.jpg
如果 subpath
有规律(比如以用户 Id
为第一级子目录),我们可以实现自定义 IFileProvider
,通过 subpath
反向映射出静态文件路径。
例如:
subpath静态文件路径/userAId/1.jpgc:\abc\userAId\1.jpg/userBId/1.jpgd:\xyz\123\userBId\1.jpg 实现创建 MyIOFileProvider
,代码如下:
public class MyIOFileProvider : IFileProvider
{
public IDirectoryContents GetDirectoryContents(string subpath)
{
return GetPhysicalFileProvider(subpath).GetDirectoryContents(subpath);
}
public IFileInfo GetFileInfo(string subpath)
{
return GetPhysicalFileProvider(subpath).GetFileInfo(subpath);
}
public IChangeToken Watch(string filter)
{
return null;
}
}
然后根据 subpath
获取对应的 PhysicalFileProvider
进行处理:
private PhysicalFileProvider GetPhysicalFileProvider(string subpath)
{
//实际可从数据库获取
if (subpath.StartsWith("/1/"))
{
return new PhysicalFileProvider(@"c:\abc");
}
if (subpath.StartsWith("/2/"))
{
return new PhysicalFileProvider(@"d:\xyz\123");
}
...
}
使用
按如下方式配置静态文件中间件:
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = new MyIOFileProvider()
});
运行效果如图:
今天,我们通过自定义 IFileProvider
,实现了动态设置静态文件存储目录。