使用FileServerOptions托管文件时,如何健壮递归获取全量文件列表?
获取FileServer托管目录的递归文件列表方案
FileServer的目录浏览组件本身仅负责生成网页展示内容,没有直接暴露返回文件列表(含递归)的内置API,但可以通过以下两种更健壮的方式实现需求:
方案一:基于文件系统API + 静态文件根路径(推荐)
利用ASP.NET Core提供的环境信息或配置好的文件提供器,结合.NET原生文件系统API来递归遍历,这是最稳定可靠的方式:
1. 针对默认Web根目录的情况
注入IWebHostEnvironment获取静态文件根路径,然后递归遍历:
private readonly IWebHostEnvironment _webEnv; public YourController(IWebHostEnvironment webEnv) { _webEnv = webEnv; } public IEnumerable<string> GetAllFilesRecursively(string subDir = "") { var rootPath = Path.Combine(_webEnv.WebRootPath, subDir); if (!Directory.Exists(rootPath)) return Enumerable.Empty<string>(); // 递归获取所有文件,转换为相对Web根的访问路径 return Directory.EnumerateFiles(rootPath, "*", SearchOption.AllDirectories) .Select(filePath => "/" + Path.GetRelativePath(_webEnv.WebRootPath, filePath).Replace("\\", "/")); }
2. 针对自定义FileProvider的情况
如果你的FileServer配置了非本地文件系统的FileProvider(比如嵌入式资源),则用IFileProvider的API遍历:
public IEnumerable<string> GetAllFilesFromProvider(IFileProvider fileProvider, string subPath = "") { var dirContents = fileProvider.GetDirectoryContents(subPath); if (!dirContents.Exists) return Enumerable.Empty<string>(); var fileList = new List<string>(); foreach (var item in dirContents) { if (item.IsDirectory) { fileList.AddRange(GetAllFilesFromProvider(fileProvider, item.Path)); } else { fileList.Add(item.Path); } } return fileList; }
你可以从FileServerOptions中直接获取配置好的FileProvider实例。
方案二:复用目录浏览组件的内部逻辑(不推荐)
ASP.NET Core的DirectoryBrowserMiddleware内部通过IDirectoryFormatter处理目录内容,但这部分属于内部实现,版本升级可能会变更:
public IEnumerable<IFileInfo> GetDirectoryContents(IFileProvider fileProvider, string path) { var contents = fileProvider.GetDirectoryContents(path); if (!contents.Exists) return Enumerable.Empty<IFileInfo>(); // 和目录浏览页面一致的排序逻辑:先目录后文件,按名称排序 return contents.OrderBy(item => item.IsDirectory).ThenBy(item => item.Name); }
该方法仅返回单级目录内容,递归仍需自行遍历子目录,且依赖内部排序规则,稳定性不如方案一。
关键注意事项
- 路径安全:必须校验输入的子目录路径,防止路径遍历攻击,比如:
var fullPath = Path.GetFullPath(Path.Combine(rootPath, subDir)); if (!fullPath.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) throw new UnauthorizedAccessException("无效路径"); - 权限控制:确保应用进程拥有目标目录及子目录的读取权限。
- 性能优化:遍历大量文件时,用
EnumerateFiles替代GetFiles实现异步非阻塞遍历。
内容的提问来源于stack exchange,提问作者Tyler
相关产品推荐
相关产品推荐

