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:                 context.Request.Path = new PathString($"{context.Request.Path}{fileName}");
  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

DefaultFilesMiddleware中间件如何显示默认页面的更多相关文章

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

    DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容.我们知道,如果直接请求的就是这个默认文件,那么前面介绍的StaticFileMiddleware中间件会 ...

  2. Tomcat:解决Tomcat可以在eclipse启动,却无法显示默认页面的操作

    解决Tomcat可以在eclipse启动,却无法显示默认页面的操作 今天在eclipse中配置好tomcat后访问不到它的主页,但是能运行自己的项目,一直找不到原因,百度之后最后解决了这个问题,总结如 ...

  3. eclipse neon配置tomcat8无法显示默认页面解决方法

    下载对应tomcat8版本到本地后,在eclipse中添加tomcat8的对应目录,输入http://localhost:8080时无法显示tomcat的index.jsp页面(会显示404页面).原 ...

  4. ui-router 视图嵌套时指定二级视图显示默认页面

    当跳转到user页面时,右边的uiview是为空的,要点击了左侧的导航才能插入模板,如何在路由中设置二级视图的默认显示页面呢? app.config(function($stateProvider, ...

  5. 设置vue启动项目后默认显示的页面

    通过配置路由,可以设置vue项目启动后默认显示的页面.路由的path设置为path:"/",启动项目后就会显示默认的组件页面. import Vue from 'vue' impo ...

  6. Jquery判断页面图片是否加载失败,加载失败则显示默认图片

    例子: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3. ...

  7. ASP.NET Core错误处理中间件[2]: 开发者异常页面

    <呈现错误信息>通过几个简单的实例演示了如何呈现一个错误页面,该过程由3个对应的中间件来完成.下面先介绍用来呈现开发者异常页面的DeveloperExceptionPageMiddlewa ...

  8. 关于Eclipse中Browser中显示html页面的总结.

    用Eclipse中的Browser显示html页面,因为"just small thing.. browser in the studio is light browser.. it can ...

  9. nginx学习(二):nginx显示默认首页解析过程

    本篇文章分析下nginx 显示默认首页的过程 如下图所示 查看config文件: # 如果忘记nginx 安装目录.使用下面命令查看 [root@XXX]# whereis nginx nginx: ...

随机推荐

  1. iOS-字符属性NSAttributedString描述

    /* 字符属性 字符属性可以应用于 attributed string 的文本中. NSString *const NSFontAttributeName;(字体) NSString *const N ...

  2. 网络编程2--毕向东java基础教程视频学习笔记

    Day 23 08 Udp接收端09 Udp键盘录入数据方式10 Udp聊天11 TCP传输12 TCP传输213 TCP练习14 TCP复制文件 08 Udp接收端 需求:定义一个应用程序,用于接收 ...

  3. 安装mysql odbc遇到error 1918.errror installing ODBC driver mysql ODBC 5.3 ANSI Drive

    环境:Windows server2008r2 安装mysql-connector-odbc-5.3.6-win32 报错 相信错误信息:Error 1918.errror installing OD ...

  4. Stanford coursera Andrew Ng 机器学习课程编程作业(Exercise 2)及总结

    Exercise 1:Linear Regression---实现一个线性回归 关于如何实现一个线性回归,请参考:http://www.cnblogs.com/hapjin/p/6079012.htm ...

  5. db2数组、函数

    一. 数组 在db2中,创建一个数组会在functions下生成两个对象:sys类型和用户类型的Array /*创建数组*/ ) array[]; /*删除数组*/ drop type arrName ...

  6. Android开发中XML布局的常用属性说明

    <!-- 常用属性说明: android:id="@+id/button" 为控件指定Id android:text="NNNNNNNNNN" 指定控件的 ...

  7. cvte 面试实习经历

    1.cvte招聘流程 我报的是Web后台开发的岗位,先是在线的笔试,笔试完了是2轮的技术面+1hr面试.之后考核一周,给作业考核.最后是终期任务完成情况的汇报和hr谈话确定你的岗位情况. 2.笔试 笔 ...

  8. Eclipse安装python注意事项

    第一次用Eclipse来开发python,在安装环境时走了很多弯路,下面记录下正确的安装方法: 1.下载Eclipse与jdk.(注意jdk与Eclipse要么都是32位,要么都是64位) 2.安装好 ...

  9. Javascript笔记--Objects

     Javascript的简单数据类型包括: 数字,字符串,true/false,null 和undefined. 其他所有值都是对象. 数组是对象,方法也是对象.属性值是除开undefined值以外的 ...

  10. 【2016-10-11】【坚持学习】【Day2】【代理模式】

    今天学习了代理模式. 定义 官方: 代理模式:给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问. Proxy Pattern: Provide a surrogate or plac ...