首页 > 其他分享 >【.NET Core框架】静态文件服务器

【.NET Core框架】静态文件服务器

时间:2023-03-06 16:47:18浏览次数:60  
标签:Core wwwroot 文件 静态 app 中间件 服务器 NET public

简介

ASP.NET Core提供以下3个中间件来处理针对静态文件的请求,它们均定义在NuGet包“Microsoft.AspNetCore.StaticFiles”中,利用这3个中间件完全可以搭建一个基于Web的文件服务器

  • StaticFileMiddleware:处理静态文件的请求
  • DirectoryBrowserMiddleware:浏览器呈现目标目录的结构
  • DefaultFilesMiddleware:默认页面的呈现

提供静态文件

静态文件默认存放在Web根目录(Web Root)中,路径为项目根目录(Content Root)下的wwwroot文件夹,也就是{Content Root}/wwwroot
如果你调用了Host.CreateDefaultBuilder方法,那么在该方法中,会通过UseContentRoot方法,将程序当前工作目录Directory.GetCurrentDirectory()设置为项目根目录。
MVC中默认开启静态文件中间件(在Configure方法中 app.UseStaticFiles()),即wwwroot目录下的文件均可以访问。
如果有需要,你也可以通过UseWebRoot扩展方法将默认的路径{Content Root}/wwwroot修改为自定义目录

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            // 配置静态资源的根目录为 mywwwroot, 默认为 wwwroot
            webBuilder.UseWebRoot("mywwwroot");
            webBuilder.UseStartup<Startup>();
        });

注意,确保 wwwroot 下的文件的属性为“如果较新则复制”或“始终复制”。

我们通过UseStaticFiles扩展方法,来注册静态文件中间件StaticFileMiddleware

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseStaticFiles();
}

如果你的项目中启用SwaggerUI,那么你会发现,即使你没有手动通过调用UseStaticFiles()添加中间件,你也可以访问 wwwroot 文件下的文件,这是因为 SwaggerUIMiddleware 中使用了 StaticFileMiddleware

提供Web根目录之外的文件

上面我们已经能够提供 wwwroot 文件夹内的静态文件了,那如果我们的文件不在 wwwroot 文件夹内,那如何提供呢?

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    // 提供 wwwroot 静态文件
    app.UseStaticFiles();

    // 提供 files 静态文件
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "files")),
        // 指定文件的访问路径,允许与 FileProvider 中的文件夹不同名
        // 如果不指定,则可通过 http://localhost:5000/file.json 获取,
        // 如果指定,则需要通过 http://localhost:5000/files/file.json 获取
        RequestPath = "/files",
        OnPrepareResponse = ctx =>
        {
            // 配置前端缓存 600s(为了后续示例的良好运行,建议先不要配置该Header)
            ctx.Context.Response.Headers.Add(HeaderNames.CacheControl, "public,max-age=600");
        }
    });
}

StaticFileOptions参数类

定义在StaticFileOptions中的前三个属性都与媒体类型的解析有关,其中ContentTypeProvider属性返回一个根据请求相对地址解析出媒体类型的IContentTypeProvider对象。如果这个IContentTypeProvider对象无法正确解析出目标文件的媒体类型,就可以利用DefaultContentType设置一个默认媒体类型。但只有将另一个名为ServeUnknownFileTypes的属性设置为True,中间件才会采用这个默认设置的媒体类型。
HttpsCompression:采用HTTPS方法请求的文件是否应该被压缩,该属性的默认值为Compress(即默认情况下会对文件进行压缩)
OnPrepareResponse:输出之前执行,利用这个委托对象可以对最终的响应进行定制

public abstract class SharedOptionsBase
{
    // 用于自定义静态文件的相对请求路径
    public PathString RequestPath { get; set; }

    // 文件提供程序
    public IFileProvider FileProvider { get; set; }

    // 是否补全路径末尾斜杠“/”,并重定向
    public bool RedirectToAppendTrailingSlash { get; set; }
}

public class StaticFileOptions : SharedOptionsBase
{
    // ContentType提供程序
    public IContentTypeProvider ContentTypeProvider { get; set; }
    
    // 如果 ContentTypeProvider 无法识别文件类型,是否仍作为默认文件类型提供
    public bool ServeUnknownFileTypes { get; set; }
    
    // 当 ServeUnknownFileTypes = true 时,若出现无法识别的文件类型,则将该属性的值作为此文件的类型
    // 当 ServeUnknownFileTypes = true 时,必须赋值该属性,才会生效
    public string DefaultContentType { get; set; }
    
    // 当注册了HTTP响应压缩中间件时,是否对文件进行压缩
    public HttpsCompressionMode HttpsCompression { get; set; } = HttpsCompressionMode.Compress;
    
    // 在HTTP响应的 Status Code 和 Headers 设置完毕之后,Body 写入之前进行调用
    // 用于添加或更改 Headers
    public Action<StaticFileResponseContext> OnPrepareResponse { get; set; }
}

案例演示:

var staticfile = new StaticFileOptions();
//设置当文件的后缀名不在已知的范围内的时候返回404
staticfile.ServeUnknownFileTypes = true;
//对于未找到对应mime的使用下面设置的默认mime值(要求ServeUnknownFileTypes=true)
staticfile.DefaultContentType = "application/x-msdownload";
// 手动设置对应的 MIME TYPE
var provider = new FileExtensionContentTypeProvider();
provider.Mappings.Add(".log", "text/plain");
provider.Mappings.Add(".dwg", "application/x-dwg");
staticfile.ContentTypeProvider = provider;
app.UseStaticFiles(staticfile);

媒体类型

StaticFileMiddleware中间件可以根据目标文件后缀输出正确的媒体类型,对于客户端来说,如果无法确定媒体类型,获取的文件就像是一部无法解码的天书,毫无价值。StaticFileMiddleware中间件利用指定的IContentTypeProvider对象来解析媒体类型。如下面的代码片段所示,IContentTypeProvider接口定义了唯一的方法TryGetContentType,从而根据当前请求的相对路径来解析这个作为输出参数的媒体类型。

public interface IContentTypeProvider
{
    bool TryGetContentType(string subpath, out string contentType);
}

StaticFileMiddleware中间件默认使用FileExtensionContentTypeProvider类型。顾名思义FileExtensionContentTypeProvider利用物理文件的扩展名来解析对应的媒体类型,并利用其Mappings属性表示的字典维护了扩展名与媒体类型之间的映射关系。常用的数百种标准的文件扩展名和对应的媒体类型之间的映射关系都会保存在这个字典中。如果发布的文件具有一些特殊的扩展名,或者需要将现有的某些扩展名映射为不同的媒体类型,都可以通过添加或者修改扩展名/媒体类型之间的映射关系来实现。

public class FileExtensionContentTypeProvider : IContentTypeProvider
{
    public IDictionary<string, string> Mappings { get; }

    public FileExtensionContentTypeProvider();
    public FileExtensionContentTypeProvider(IDictionary<string, string> mapping);

    public bool TryGetContentType(string subpath, out string contentType);
}

启用目录浏览

通过UseDirectoryBrowser,注册DirectoryBrowserMiddleware中间件,可以让我们在浏览器中以目录的形式来访问文件列表。

public void ConfigureServices(IServiceCollection services)
        {
            services.AddDirectoryBrowser();
      }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
          // 通过 http://localhost:5000,即可访问 wwwroot 目录
          app.UseDirectoryBrowser();

          // 通过 http://localhost:5000/files,即可访问 files 目录
          app.UseDirectoryBrowser(new DirectoryBrowserOptions
          {
              // 如果指定了没有在 UseStaticFiles 中提供的文件目录,虽然可以浏览文件列表,但是无法访问文件内容
              FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "files")),
              // 这里一定要和 StaticFileOptions 中的 RequestPath 一致,否则会无法访问文件
              RequestPath = "/files"
          });
        }

相对路径设置为"/img",那么则可以通过 http://localhost:5000/img/ 进行目录的浏览,并打开文件

启用默认文件

要提供默认文件,必须在UseStaticFiles前调用UseDefaultFilesUseDefaultFiles实际上用于重写URL,不提供文件,需通过UseStaticFiles启用静态文件中间件来提供文件。
默认文件的访问顺序为:default.htm→default.html→index.htm→index.html,且必须放在wwwroot目录下

            // 会去 wwwroot 寻找 default.htm 、default.html 、index.htm 或 index.html 文件作为默认页
            //app.UseDefaultFiles();

            // 设置 files 目录的默认页
            var defaultFilesOptions = new DefaultFilesOptions();
            defaultFilesOptions.DefaultFileNames.Clear();
            // 指定默认页名称
            defaultFilesOptions.DefaultFileNames.Add("index1.html");
            // 指定请求路径
            defaultFilesOptions.RequestPath = "/files";
            // 指定默认页所在的目录
            defaultFilesOptions.FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "files"));
            app.UseDefaultFiles(defaultFilesOptions);

            //作用于wwwroot目录,即根目录
            app.UseStaticFiles();

UseFileServer(融合静态文件、默认文件、目录浏览)

            //提供静态文件和默认文件,未启用目录浏览。
            app.UseFileServer();

            //提供静态文件、启用目录浏览。
            //app.UseFileServer(enableDirectoryBrowsing: true);

            //启用静态文件、默认文件和及 MyStaticFiles 的目录浏览
            //app.UseStaticFiles();
            //app.UseFileServer(new FileServerOptions
            //{
            //    FileProvider = new PhysicalFileProvider(
            //        Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
            //        RequestPath = "/MyStaticFiles",
            //        EnableDirectoryBrowsing = true,//启用目录浏览
            //        EnableDefaultFiles=true,//启用默认文件
            //});

参考:
https://www.cnblogs.com/artech/p/static-file-middleware-01.html
https://www.cnblogs.com/xiaoxiaotank/p/15496538.html

 

转 https://www.cnblogs.com/fanfan-90/p/12152445.html

标签:Core,wwwroot,文件,静态,app,中间件,服务器,NET,public
From: https://www.cnblogs.com/wl-blog/p/17184395.html

相关文章

  • ASP.NET Core 使用app.UseStaticFiles配置静态文件中间件,达到类似IIS中虚拟目录的效果
    1、项目中静态文件存放在wwwroot文件夹之下,如下:要访问nihao.jpg这个文件夹,url路径可以这样写:<imgsrc="~/images/inhao.jpg"alt="pic"/>wwwrootcssimagesnihao.jpgjs那......
  • ASP.NET Core文件上传与下载(多种上传方式)
    前言前段时间项目上线,实在太忙,最近终于开始可以研究研究ASP.NETCore了.打算写个系列,但是还没想好目录,今天先来一篇,后面在整理吧.ASP.NETCore2.0发展到现在,已......
  • CentOS-1810系统DHCP服务器ISC DHCP软件配置说明
    DHCP全称DynamicHostconfigurationprotocol,动态主机配置协议。是一个局域网的网络协议,使用UDP协议工作,它可以为客户机自动分配IP地址、子网掩码以及缺省网关、DNS服务......
  • 如何让 WinDebug Preview 加载 Dotnet Core 的 SOS.dll 进行调试
    一、前言最近我在使用WinDebug进行系统调试,也是在学习《Net高级调试》这本书。以前听过WinDebug调试器,但是没有使用过,由于最近想起来了,就好好的研究一下,学习一......
  • .NET7依赖注入 延迟加载模式
    .NET7依赖注入延迟加载模式延迟加载(LazyLoading)模式是指在服务被首次请求时,才对其进行初始化。这种模式可以减少程序启动时间和资源消耗。示例代码如下://MyService类......
  • .NET7依赖注入 装饰器模式
    ##.NET7依赖注入装饰器模式装饰器(Decorator)模式是一种在不改变原始类的情况下增强其功能的模式。在DI中,装饰器模式常用于在不改变原始服务的实现的情况下增强其功能,例......
  • .NET7依赖注入
    依赖注入(DependencyInjection,简称DI)功能,使得应用程序可以更加容易地管理组件之间的依赖关系。在.NET7中,DI是通过Microsoft.Extensions.DependencyInjection命名空......
  • exchange2016服务器的DAG的部署
    现在大家都开始用exchange2016的邮件系统了。原先的的exchange2010也需要升级了。要么升级,要exchange2010和exchange2016共存。我是在把原来虚拟机的环境卸载后重新安装的......
  • 如何从 .NET 中的字符串中删除变音符号(重音符号)?
    我正在尝试转换一些加拿大法语字符串,基本上,我希望能够在保留字母的同时去掉字母中的法语重音符号。(例如转换é为e,所以crèmebrûlée会变成cremebrulee)实现这一目标......
  • iis 启用服务器端调试后,浏览器上不再显示错误提示信息
    今天发现一个奇葩现象,一个asp文件里的代码运行出错了,但是浏览器并不会显示错误的提示信息,显示一个空白页,并且通过查看httpheader发现返回的http状态码是 200 ......