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
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号 蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
8月前
|
Go
在golang中发起http请求以获取访问域名的ip地址实例(使用net, httptrace库)
这只是追踪我们的行程的简单方法,不过希望你跟着探险家的脚步,即使是在互联网的隧道中,也可以找到你想去的地方。接下来就是你的探险之旅了,祝你好运!
459 26
|
C# Android开发 iOS开发
2025年全面的.NET跨平台应用框架推荐
2025年全面的.NET跨平台应用框架推荐
582 23
|
开发框架 算法 中间件
ASP.NET Core 中的速率限制中间件
在ASP.NET Core中,速率限制中间件用于控制客户端请求速率,防止服务器过载并提高安全性。通过`AddRateLimiter`注册服务,并配置不同策略如固定窗口、滑动窗口、令牌桶和并发限制。这些策略可在全局、控制器或动作级别应用,支持自定义响应处理。使用中间件`UseRateLimiter`启用限流功能,并可通过属性禁用特定控制器或动作的限流。这有助于有效保护API免受滥用和过载。 欢迎关注我的公众号:Net分享 (239字符)
315 1
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
363 2
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
285 5
|
JSON 算法 安全
JWT Bearer 认证在 .NET Core 中的应用
【10月更文挑战第30天】JWT(JSON Web Token)是一种开放标准,用于在各方之间安全传输信息。它由头部、载荷和签名三部分组成,用于在用户和服务器之间传递声明。JWT Bearer 认证是一种基于令牌的认证方式,客户端在请求头中包含 JWT 令牌,服务器验证令牌的有效性后授权用户访问资源。在 .NET Core 中,通过安装 `Microsoft.AspNetCore.Authentication.JwtBearer` 包并配置认证服务,可以实现 JWT Bearer 认证。具体步骤包括安装 NuGet 包、配置认证服务、启用认证中间件、生成 JWT 令牌以及在控制器中使用认证信息
522 2
|
数据采集 JSON API
.NET 3.5 中 HttpWebRequest 的核心用法及应用
【9月更文挑战第7天】在.NET 3.5环境下,HttpWebRequest 类是处理HTTP请求的一个核心组件,它封装了HTTP协议的细节,使得开发者可以方便地发送HTTP请求并接收响应。本文将详细介绍HttpWebRequest的核心用法及其实战应用。
745 6
|
API
使用`System.Net.WebClient`类发送HTTP请求来调用阿里云短信API
使用`System.Net.WebClient`类发送HTTP请求来调用阿里云短信API
269 0
|
消息中间件 存储 中间件
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
【消息中间件】详解三大MQ:RabbitMQ、RocketMQ、Kafka
13059 1
|
消息中间件 编解码 Docker
Docker部署RabbitMQ消息中间件
【7月更文挑战第4天】Docker部署RabbitMQ消息中间件
531 3