原文链接:https://blog.csdn.net/sD7O95O/article/details/107587430
现在部署Asp.Net Core应用已经不再限制于Windows的IIS上,更多的是Docker容器、各种反向代理来部署。也有少部分用IIS部署的,IIS部署确实是又快又简单,图形化操作三下五除二就可以发布好一个系统了。在过去Asp.Net MVC 项目部署的时候,还常常使用IIS一个功能——虚拟目录。
虚拟目录可以直接定位到非项目的其他路径,将路径作为网站的一部分,可实现上传文件保存到其他盘符或间接的使用项目以外的静态文件。在Asp.Net MVC中从虚拟路径中存取文件也很简单,如:
Server.MapPath("~/Upload/liohuang.jpg");
但在Asp.Net Core上不同,它被抽象出一个“文件系统”,也就是FileProvider。FileProvider是对所有实现了IFileProvider接口的所有类型以及对应对象的统称,文件系统在Artech蒋老师的《.NET Core的文件系统[2]:FileProvider是个什么东西?》文章中已经透析了,这里不在罗里吧嗦了。
这篇文章要解决的内容是:Asp.Net Core应用中,如何优雅的使用“虚拟目录”。
实操
首先,新建一个.Net Core WebApi空项目部署在D盘,“虚拟目录”假设物理路径在F盘,分别创建三个测试目录 F:/test1 、 F:/test2 和 F:/test3 ,目录里分别存放对应的文件1/2/3.jpg 和 mybook.txt 。
读取虚拟目录文件
在 Startup.ConfigureServices 注入 IFileProvider :
services.AddSingleton<IFileProvider>(new PhysicalFileProvider("F:\\test1"));
新建一个控制器,读取 mybook.txt 中的内容:
[ApiController] [Route("[controller]/[action]")] public class LioHuangController : ControllerBase { [HttpGet] public object GetFiles([FromServices]IFileProvider fileProvider) { var file = fileProvider.GetFileInfo("mybook.txt"); if (file.Exists) { return ReadTxtContent(file.PhysicalPath); } return 0; } /// <summary> /// 读取文本 /// </summary> private string ReadTxtContent(string Path) { if (!System.IO.File.Exists(Path)) { return "Not found!"; } using (StreamReader sr = new StreamReader(Path, Encoding.UTF8)) { StringBuilder sb = new StringBuilder(); string content; while ((content = sr.ReadLine()) != null) { sb.Append(content); } return sb.ToString(); } } }
访问接口,接口读取文件之后,返回内容:
IFileProvider 接口采用目录来组织文件,并统一使用 IFileInfo 接口来表示, PhysicalPath 表示文件的物理路径。
public interface IFileInfo { bool Exists { get; } bool IsDirectory { get; } DateTimeOffset LastModified { get; } string Name { get; } string PhysicalPath { get; } Stream CreateReadStream(); }
如多个虚拟目录,怎么处理?简单,注入多个 IFileProvider 即可:
services.AddSingleton<IFileProvider>(new PhysicalFileProvider("F:\\test1")); services.AddSingleton<IFileProvider>(new PhysicalFileProvider("F:\\test2")); services.AddSingleton<IFileProvider>(new PhysicalFileProvider("F:\\test3"));
代码修改为:
public object GetFiles([FromServices] IEnumerable<IFileProvider> fileProviders)
IEnumerable<IFileProvider> fileProviders 接口数组将会有三个,按注入的顺序对应不同的目录。当然,注入 IFileProvider 的时候,就可以封装一层了,下面再讲。
另外,有的说直接 ReadTxtContent("F:\test1\mybook.txt"); 不香吗?香,Asp.Net Core的访问权限要比Asp.Net MVC之前老版本项目要高许多,确实是可以直接读取项目以外的文件,但是并不适合直接去访问,除非说你只有一个地方使用到,那么就可以直接读取,但静态的文件的访问,就访问不到了,仅仅是后台读取而已。所以统一使用 IFileProvider 来约束,代码的可维护性要高许多。
静态文件访问
在Startup.Configure设置静态文件目录,即可:
app.UseStaticFiles(new StaticFileOptions() { FileProvider = new PhysicalFileProvider("F:\\test1"), RequestPath = "/test" });; app.UseStaticFiles(new StaticFileOptions() { FileProvider = new PhysicalFileProvider("F:\\test2"), RequestPath = "/test" }); app.UseStaticFiles(new StaticFileOptions() { FileProvider = new PhysicalFileProvider("F:\\test3"), RequestPath = "/test" });
FileProvider 同上面所说的,设置好物理路径的根目录, RequestPath 则是访问路径的前缀,必须是斜杆 “/” 开头,访问地址前缀则为:
https://localhost:5001/test/
设置好之后,就可以访问项目以外的路径了。
标签:Core,Asp,虚拟目录,new,Net,FileProvider From: https://www.cnblogs.com/Dongmy/p/18260881