ASP.NET Core应用针对静态文件请求的处理[5]: DefaultFilesMiddleware中间件如何显示默认页面

DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容。我们知道,如果直接请求的就是这个默认文件,那么前面介绍的StaticFileMiddleware中间件会将这个文件响应给客户端。如果我们能够将针对目录的请求重定向到这个默认文件上,一切就迎刃而解了。实际上DefaultFilesMiddleware中间件的实现逻辑很简单,它采用URL重写的形式修改了当前请求的地址,即将针对目录的URL修改成针对默认文件的URL。[本文已经同步到《ASP.NET Core框架揭秘》之中]

我们照例先来看看DefaultFilesMiddleware类型的定义。和其他两个中间件类似,DefaultFilesMiddleware的构造就有一个IOptions<DefaultFilesOptions>类型的参数来指定相关的配置选项。由于DefaultFilesMiddleware中间件本质上依然体现了请求路径与某个物理目录的映射,所以DefaultFilesOptions依然派生于SharedOptionsBase。DefaultFilesOptions的DefaultNames属性包含了预定义的默认文件名,我们可以看到它默认包含四个名称(default.htm、default.html、index.htm或者index.html)。

   1: public class DefaultFilesMiddleware
   2: {
   3:     public DefaultFilesMiddleware(RequestDelegate next, IHostingEnvironment hostingEnv, IOptions<DefaultFilesOptions> options);
   4:     public Task Invoke(HttpContext context);
   5: }
   6:  
   7: public class DefaultFilesOptions : SharedOptionsBase
   8: {
   9:     public IList<string> DefaultFileNames { get; set; }
  10:  
  11:     public DefaultFilesOptions() : this(new SharedOptions()){}
  12:     public DefaultFilesOptions(SharedOptions sharedOptions) : base(sharedOptions)
  13:     {
  14:         this.DefaultFileNames = new List<string> { "default.htm", "default.html", "index.htm", "index.html" };
  15:     }    
  16: }

我们同样采用一种比较易于理解的形式重新定义这个DefaultFilesMiddleware类型以便于读者朋友理解它具体采用的请求处理逻辑。如下面的代码片段所示,DefaultFilesMiddleware和DirectoryBrowserMiddleware一样会对请求做相应的验证。如果当前目录下存在某个默认文件,那么它会将当前请求的URL修改成指向这个默认文件的URL。值得一提的是,DefaultFilesMiddleware中间件要求访问目录的请求路劲必须以字符“/”作为后缀,否则会在目前的路径上添加这个后缀并针对最终的路径发送一个重定向。

   1: public class DefaultFilesMiddleware
   2: {
   3:     private RequestDelegate         _next;
   4:     private DefaultFilesOptions     _options;
   5:   
   6:     public DefaultFilesMiddleware(RequestDelegate next, IHostingEnvironment env, IOptions<DefaultFilesOptions> options)
   7:     {
   8:         _next                     = next;
   9:         _options                  = options.Value;
  10:         _options.FileProvider     = _options.FileProvider ?? env.WebRootFileProvider;
  11:     }
  12:  
  13:     public async Task Invoke(HttpContext context)
  14:     {
  15:         //只处理GET和HEAD请求
  16:         if (!new string[] { "GET", "HEAD" }.Contains(context.Request.Method,StringComparer.OrdinalIgnoreCase))
  17:         {
  18:             await _next(context);
  19:             return;
  20:         }
  21:  
  22:         //检验当前路径是否与注册的请求路径相匹配
  23:         PathString path = new PathString(context.Request.Path.Value.TrimEnd('/') + "/");
  24:         PathString subpath;
  25:         if (!path.StartsWithSegments(_options.RequestPath, out subpath))
  26:         {
  27:             await _next(context);
  28:             return;
  29:         }
  30:  
  31:         //检验目标目录是否存在
  32:         if (!_options.FileProvider.GetDirectoryContents(subpath).Exists)
  33:         {
  34:             await _next(context);
  35:             return;
  36:         }
  37:  
  38:         //检验当前目录是否包含默认文件
  39:         foreach (var fileName in _options.DefaultFileNames)
  40:         {
  41:             if (_options.FileProvider.GetFileInfo($"{subpath}{fileName}").Exists)
  42:             {
  43:                 //如果当前路径不以"/"作为后缀,会响应一个针对“标准”URL的重定向
  44:                 if (!context.Request.Path.Value.EndsWith("/"))
  45:                 {
  46:                     context.Response.StatusCode = 302;
  47:                     context.Response.GetTypedHeaders().Location = new Uri(path.Value + context.Request.QueryString);
  48:                     return;
  49:                 }
  50:                 //将针对目录的URL更新为针对默认文件的URL
  51:                 
  52:             }
  53:         }
  54:         await _next(context);
  55:     }
  56: }

正是因为DefaultFilesMiddleware中间件采用URL重写的方式来响应默认文件,所以它最终依赖StaticFileMiddleware中间件来响应默认文件,所以针对后者的注册时必须的。也正是这个原因,这个中间件需要优先注册以确保URL重写发生在StaticFileMiddleware响应文件之前。

 



ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件
ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求
ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求
ASP.NET Core应用针对静态文件请求的处理[4]: DirectoryBrowserMiddleware中间件如何呈现目录结构
ASP.NET Core应用针对静态文件请求的处理[5]: DefaultFilesMiddleware中间件如何显示默认页面

作者:蒋金楠
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

原文链接

时间: 2024-09-13 21:24:40

ASP.NET Core应用针对静态文件请求的处理[5]: DefaultFilesMiddleware中间件如何显示默认页面的相关文章

ASP.NET Core应用针对静态文件请求的处理[4]: DirectoryBrowserMiddleware中间件如何呈现目录结构

和StaticFileMiddleware中间件一样,DirectoryBrowserMiddleware中间本质上还是定义了一个请求地址与某个物理目录之间的映射关系,而目标目录体现为一个FileProvider对象.当这个中间件接收到匹配的请求后,会根据请求地址解析出对应目录的相对路径,并利用这个FileProvider获取目录的内容.目录的内容最终会以一个HTML文档的形式被定义,而此HTML最终会被这个中间件作为响应的内容,"目录浏览器"的实现原理就这么简单. [本文已经同步到&

ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求

我们通过<以Web的形式发布静态文件>和<条件请求与区间请求>中的实例演示,以及上面针对条件请求和区间请求的介绍,从提供的功能和特性的角度对这个名为StaticFileMiddleware的中间进行了全面的介绍,接下来我们将更近一步,将从实现原理的角度来进一步认识这个中间件. [本文已经同步到<ASP.NET Core框架揭秘>之中] 目录 一.StaticFileMiddleware 二.ContentTypeProvider 三.利用配置指定StaticFileOp

ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件

虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件的请求.针对不同格式的静态文件请求的处理,ASP.NET Core为我们提供了三个中间件,它们将是本系列文章论述的重点.不过在针对对它们展开介绍之前,我们照理通过一些简单的实例来体验一下如何在一个ASP.NET Core应用中发布静态文件.[本文已经同步到<ASP.NET Core框架揭秘>之中]

ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求

通过调用ApplicationBuilder的扩展方法UseStaticFiles注册的StaticFileMiddleware中间件帮助我们处理针对文件的请求.对于StaticFileMiddleware处理请求的逻辑,大部分读者都应该想得到:它根据请求的地址找到目标文件的路径,然后利用注册的ContentTypeProvider根据路径解析出与文件内容相匹配的媒体类型,默认情况下得到的媒体类型是根据目标文件的扩展名解析出来的.解析出来的媒体类型将作为响应报头Content-Type的值.St

解析如何利用一个ASP.NET Core应用来发布静态文件_实用技巧

虽然ASP.NET Core是一款"动态"的Web服务端框架,但是在很多情况下都需要处理针对静态文件的请求,最为常见的就是这对JavaScript脚本文件.CSS样式文件和图片文件的请求.针对不同格式的静态文件请求的处理,ASP.NET Core为我们提供了三个中间件,它们将是本系列文章论述的重点.不过在针对对它们展开介绍之前,我们照理通过一些简单的实例来体验一下如何在一个ASP.NET Core应用中发布静态文件. 目录 一.以Web的形式读取文件 二.浏览目录内容 三.显示默认页面

asp.net core 之静态文件目录的操作

文章前言 之前写了一篇关于模拟登录的文章,自我感觉内容不太丰富,今天的这篇文章,希望在内容上能丰富些.本人缺少写文章的经验,技术上也是新手,但我会努力的,希望大家多多支持小弟. asp.net core项目静态文件 创建一个asp.net core 项目的静态文件一般是放在项目目录下wwwroot文件夹,文件目录如下. 如何将静态文件注入到项目中 在startup.cs文件的Configure方法中写入: app.UseStaticFiles(); 这方法的默认路径正是上面所说的wwwroot目

ASP.NET Core管道深度剖析(3):管道是如何处理HTTP请求的?

我们知道ASP.NET Core请求处理管道由一个服务器和一组有序的中间件组成,所以从总体设计来讲是非常简单的,但是就具体的实现来说,由于其中涉及很多对象的交互,我想很少人能够地把它弄清楚.为了让读者朋友们能够更加容易地理解管道处理HTTP请求的总体流程,我们根据真实管道的实现原理再造了一个"模拟管道"并在此管道上开发了一个发布图片的应用,这篇文章旨在为你讲述管道是如何处理HTTP请求的 目录 一.HttpApplication     FeatureCollection     Ho

asp.net core实现文件上传功能_实用技巧

本文实例为大家分享了单文件上传.多文件上传的功能,供大家参考,具体内容如下 单文件上传 上传文件在Web应用程序中是一个常见的功能.在asp.net core中上传文件并保存在服务器上,是很容易的.下面就来演示一下怎么样在 ASP.NET Core项目中进行文件上传.  首先,创建一个 asp.net core 项目,然后在Controller文件件添加一个HomeController,然后在 Views 文件夹的 Home 文件夹里添加一个 New.cshtml 视图文件.如下图:  添加一个

聊聊ASP.NET Core默认提供的这个跨平台的服务器——KestrelServer

跨平台是ASP.NET Core一个显著的特性,而KestrelServer是目前微软推出了唯一一个能够真正跨平台的Server.KestrelServer利用一个名为KestrelEngine的网络引擎实现对请求的监听.接收和响应.KetrelServer之所以具有跨平台的特质,源于KestrelEngine是在一个名为libuv的跨平台网络库上开发的. 目录 一.libuv 二.KestrelServer 三.KestrelServerOptions 四.ApplicationLifetim