ASP.NET5 中静态文件的各种使用方式服务端的静态文件开启目录浏览呈现默认文件使用UseFileServer方法文件类型基于IIS的考虑最佳实践

所谓静态文件,包含HTML文件,css文件、图片文件和js文件等,他们是服务器直接读取到客户端的一些资源,在这篇文章中,我们将解释关于ASP.NET5和静态文件的一些内容。

服务端的静态文件

默认情况下,静态文件被存放在项目的wwwroot目录下,而wwwroot的地址被定义在project.json文件中:

{
     "webroot": "wwwroot",
    ...
}

静态文件被存储在wwwroot下的任何目录中,它被客户端以相对路径的方式访问,例如,当你在Visual Studio中创建一个默认的Web应用程序时,一些文件夹就已经创建在了wwwroot目录下:js、images、css。直接反问这些问一个在images目录中的图片的路径看起来应该是这样的:

http://项目地址/images/图片名称

为了静态文件可以被使用,你必须配置中间件(Middleware)在管道(pipeline)来添加静态文件,这由在Startup类中的Configure方法中调用app的UseStaticFiles来完成:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...
  // Add static files to the request pipeline.
  app.UseStaticFiles();
  ...

现在,假设我们在项目中拥有一些你希望在项目中引用的静态文件但是它处在wwwroot外部,例如以下这个示例:

  • wwwroot
    • css
    • images
    • ...
  • MyStaticFiles
    • test.png

为了让用户可以访问到test.png文件,你可以向下文这样配置静态文件中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...
  // Add MyStaticFiles static files to the request pipeline.
  app.UseStaticFiles(new StaticFileOptions()
  {
      FileProvider = new PhysicalFileProvider(@"D:\Source\WebApplication1\src\WebApplication1\MyStaticFiles"),
      RequestPath = new PathString("/StaticFiles")
  });
  ...

这样处理之后,你可以使用http://<yourApp>/StaticFiles/test.png来访问上文中所述的test.png文件。

开启目录浏览

目录浏览可以让应用程序的用户看到指定目录的文件和目录列表,默认情况下,这个功能是没有开启的,如果用户尝试去显示一个目录,将会收到一个错误。开发人员可以通过调用app的UseDirectoryBrower扩展方法开启这个功能:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...
  // Turn on directory browsing for the current directory.
  app.UseDirectoryBrowser();
  ...

然后,如果你访问应用的images目录,将会展示为这样:

现在,假设我们存在一个想要被用户访问但是处在wwwroot外的文件夹MyStaticFiles,为了可以让用户通过目录浏览查看到这个文件夹,可以这样配置静态文件中间件:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...
  // Add the ability for the user to browse the MyStaticFiles directory.
  app.UseDirectoryBrowser(new DirectoryBrowserptions()
  {
      FileProvider = new PhysicalFileProvider(@"D:\Source\WebApplication1\src\WebApplication1\MyStaticFiles"),
      RequestPath = new PathString("/StaticFiles")
  });
  ...

呈现默认文件

为了让你的应用程序不需要URL全路径就可以展示一个默认页面给用户,你可以通过调用app的UseDefaultFiles扩展方法来实现。注意你必须同样调用UseStaticFiles方法,这是因为UseDefaultFiles方法只是重写了URL。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...
  // Serve the default file, if present.
  app.UseDefaultFiles();
  app.UseStaticFiles();
  ...

假如你知识这样简单的调用了UseDefaultFiles方法并且使用一个目录的Url进行访问,那么这个中间件将会搜索下列中的一个文件,假如他们中有一个被找到,那么这个文件将会作为默认的文件被展示:

  • default.htm
  • default.html
  • index.htm
  • index.html

为了可以允许指定一个默认的文件而不是上文中所述的这些,可以实例化一个DefaultFileOptions对象,并且设置它的DefaultFileNames属性来指定默认文件,然后将这个对象传给UseDefaultFiles方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...
  // Serve my app-specific default file, if present.
  DefaultFilesOptions options = new DefaultFilesOptions();
  options.DefaultFileNames.Clear();
  options.DefaultFileNames.Add("mydefault.html");
  app.UseDefaultFiles(options);
  app.UseStaticFiles();
  ...

现在,如果用户浏览webroot目录并且在这个目录下存在一个mydefault.html文件,那么这个文件将会被浏览器显示。

但是如果你向展示的默认文件不在wwwroot目录下呢?你可以调用UseStaticFiles和UseDefaultFiles方法,并且给这两个方法传入相同的值,然后我们更推荐使用下文中将讲述的UseFileServer方法。

使用UseFileServer方法

作为对UseStaticFiles、UseDefaultFiles和UseDirectoryBrowser方法的补充,有一个UseFileServer的方法集合前三个方法的功能为一身,我们可以这样使用它:

// Enables all static file middleware (serving of static files, default files, and directory browsing).
app.UseFileServer(enableDirectoryBrowsing: true);

现在,加入你想要展示存在于wwwroot目录外部的文件,可以实例化并且配置一个options对象,然后你可以把它作为参数传给UseFileServer方法。例如,现在存在这样的目录结构:

  • wwwroot
    • css
    • images
    • ...
  • MyStaticFiles
    • test.png
    • default.html

你可能希望使用静态文件并设置默认文件并且可以浏览MyStaticFiles目录,在下文中的代码段中,你可以只调用一个UseFileServer方法来实现这些需求:

// Enable all static file middleware (serving of static files, default files,
// and directory browsing) for the MyStaticFiles directory.
app.UseFileServer(new FileServerOptions()
{
    FileProvider = new PhysicalFileProvider(@"D:\Source\WebApplication1\src\WebApplication1\MyStaticFiles"),
    RequestPath = new PathString("/StaticFiles"),
    EnableDirectoryBrowsing = true
});

文件类型

ASP.NET 静态文件中间件定义了将近400中文件类型,加入用户视图访问一个中间件不包含的文件类型,ASP.NET将不会尝试去提供这个文件。

假如现在存在如下的目录结构:

  • wwwroot
    • css
    • images
      • test.image
    • ...

使用这样的目录结构,你可以通过上文中所述方法开启目录浏览和静态文件访问的功能,你可以通过http://localtion/images 目录看到test.image文件,但是当你点击这个文件,你将收到一个404错误--就像它真的不存在似得。为了允许展示这些未知类型的文件,可以设置StaticFileOptions的ServeUnknownFileTypes属性为true并且为DefaultContentType属性设置相应的内容类型(参考常用MIME内容类型列表):

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...
  // Serve static files and allow directory browsing.
  app.UseDirectoryBrowser();
  app.UseStaticFiles(new StaticFileOptions
  {
    ServeUnknownFileTypes = true,
    DefaultContentType = "image/png"
  });

现在,如果浏览器试图访问一个未知类型的文件,浏览器将会把它当作一个图片来渲染。

到目前为止,你已经看到如何为一个ASP.NET不识别的文件类型指定一个默认的内容类型,然而,如果你有多个文件类型是对于ASP.NET为止的改怎么办?还好我们有FileExtensionContentTypeProvider类型。

FileExtensionContentTypeProvider包含一个内部的列表映射于MIME内容类型和文件后缀,指定一个自定义的内容类型,只需要简单的实例化一个FileExtensionContentTypeProvider对象,然后添加一个映射到Mappings属性,如下文所示:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...

  // Allow directory browsing.
  app.UseDirectoryBrowser();

  // Set up custom content types - associating file extension to MIME type
  var provider = new FileExtensionContentTypeProvider();
  provider.Mappings.Add(".myapp", "application/x-msdownload");

  // Serve static files.
  app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider });

  ...

基于IIS的考虑

IIS用户一个本地的静态文件模块,它不依赖于ASP.NET静态文件中间件组件,ASP.NET模块在IIS本地组件之前运行,它拥有比IIS本地组件更高的优先权,而在ASP.NET BETA 7中,IIS已经更改,所以没有被ASP.NET处理的请求将会返回一个空的404响应,而不是由IIS本地模块来执行,如果希望由IIS本地模块来处理,在Configure方法的最后添加以下代码:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
  ...

  ...
  // Enable the IIS native module to run after the ASP.NET middleware components.
  // This call should be placed at the end of your Startup.Configure method so that
  // it doesn't interfere with other middleware functionality.
  app.RunIISPipeline();
}

最佳实践

代码文件应该被置于应用程序的webroot目录以外,这样可以建立静态文件和源代码的完全的隔离。

原文地址:http://docs.asp.net/en/latest/fundamentals/static-files.html

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏偏前端工程师的驿站

Httpd运维日志:通过apxs添加模块

Brief                                   在部署Httpd时为方便管理和安全等原因,我们仅会安装所需的模块,那么后期功能扩...

1816
来自专栏Ryan Miao

使用log4j配置不同文件输出不同内容

敲代码中很不注意写日志,虽然明白很重要。今天碰到记录日志,需要根据内容分别输出到不同的文件。 参考几篇文章: 感觉最详细:http://blog.csdn.ne...

2467
来自专栏智能合约

crontab定时任务详解

1474
来自专栏冷冷

【系统日志】log4j配置学习总结

Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局)。这里可简单理解为日志类别,日志要输出的地方和日志以...

1766
来自专栏Windows Community

New Windows 10 SDK - Multi-instance UWP apps

概述 前面一篇 About Windows 10 SDK Preview Build 17110 中,我们简单介绍了 Multi-instance UWP Ap...

3219
来自专栏三流程序员的挣扎

git rebase

rebase 这个命令正式工作中基本上没有用过,只是学习时曾经写过 Demo,但具体指令的含义不是太理解,总觉得没有 merge 来得有掌控感,而且过去使用代码...

633
来自专栏张戈的专栏

Python远程控制模块paramiko遇到的问题及解决记录

最近一直在开发自动化运维发布平台,底层命令行、文件通道主要基于 paramiko 模块,使用过程中遇到各种各样的问题,本文主要用于收集问题及解决记录,以备后续使...

4458
来自专栏Linyb极客之路

log4j配置学习总结

Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局)。这里可简单理解为日志类别,日志要输出的地方和日志以...

893
来自专栏dotnet core相关

WCF入门学习(3)

废话不多说,前两集大致介绍了一下什么是WCF以及和WCF相关的WebService和.net Remoting的一些东西,今天主角要上场,开始WCF的实现相关的...

642
来自专栏潇涧技术专栏

Make Your Octopress Easy

写了几个shell脚本让你在Octopress上写博客更加轻松些,至少让我轻松了很多,哈哈哈。

782

扫描关注云+社区