ASP.NET Core应用针对静态文件请求的处理[5]: DefaultFilesMiddleware中间件如何显示默认页面
2016-12-14 08:10
1346 查看
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)。
我们同样采用一种比较易于理解的形式重新定义这个DefaultFilesMiddleware类型以便于读者朋友理解它具体采用的请求处理逻辑。如下面的代码片段所示,DefaultFilesMiddleware和DirectoryBrowserMiddleware一样会对请求做相应的验证。如果当前目录下存在某个默认文件,那么它会将当前请求的URL修改成指向这个默认文件的URL。值得一提的是,DefaultFilesMiddleware中间件要求访问目录的请求路劲必须以字符“/”作为后缀,否则会在目前的路径上添加这个后缀并针对最终的路径发送一个重定向。
正是因为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中间件如何显示默认页面
我们照例先来看看DefaultFilesMiddleware类型的定义。和其他两个中间件类似,DefaultFilesMiddleware的构造就有一个IOptions<DefaultFilesOptions>类型的参数来指定相关的配置选项。由于DefaultFilesMiddleware中间件本质上依然体现了请求路径与某个物理目录的映射,所以DefaultFilesOptions依然派生于SharedOptionsBase。DefaultFilesOptions的DefaultNames属性包含了预定义的默认文件名,我们可以看到它默认包含四个名称(default.htm、default.html、index.htm或者index.html)。
[code] public class DefaultFilesMiddleware
{
public DefaultFilesMiddleware(RequestDelegate next, IHostingEnvironment hostingEnv, IOptions<DefaultFilesOptions> options);
public Task Invoke(HttpContext context);
}
public class DefaultFilesOptions : SharedOptionsBase
{
public IList<string> DefaultFileNames{ get; set;}
public DefaultFilesOptions() : this(new SharedOptions()){}
public DefaultFilesOptions(SharedOptions sharedOptions) : base(sharedOptions)
{
this.DefaultFileNames = new List<string>{ "default.htm", "default.html", "index.htm", "index.html"};
}
}
我们同样采用一种比较易于理解的形式重新定义这个DefaultFilesMiddleware类型以便于读者朋友理解它具体采用的请求处理逻辑。如下面的代码片段所示,DefaultFilesMiddleware和DirectoryBrowserMiddleware一样会对请求做相应的验证。如果当前目录下存在某个默认文件,那么它会将当前请求的URL修改成指向这个默认文件的URL。值得一提的是,DefaultFilesMiddleware中间件要求访问目录的请求路劲必须以字符“/”作为后缀,否则会在目前的路径上添加这个后缀并针对最终的路径发送一个重定向。
[code] public class DefaultFilesMiddleware
{
private RequestDelegate _next;
private DefaultFilesOptions _options;
public DefaultFilesMiddleware(RequestDelegate next, IHostingEnvironment env, IOptions<DefaultFilesOptions> options)
{
_next = next;
_options= options.Value;
_options.FileProvider = _options.FileProvider ?? env.WebRootFileProvider;
}
public async Task Invoke(HttpContext context)
{
//只处理GET和HEAD请求
if (!new string[]{ "GET", "HEAD"}.Contains(context.Request.Method,StringComparer.OrdinalIgnoreCase))
{
await _next(context);
return;
}
//检验当前路径是否与注册的请求路径相匹配
PathString path = new PathString(context.Request.Path.Value.TrimEnd('/') + "/");
PathString subpath;
if (!path.StartsWithSegments(_options.RequestPath, out subpath))
{
await _next(context);
return;
}
//检验目标目录是否存在
if (!_options.FileProvider.GetDirectoryContents(subpath).Exists)
{
await _next(context);
return;
}
//检验当前目录是否包含默认文件
foreach (var fileName in _options.DefaultFileNames)
{
if (_options.FileProvider.GetFileInfo($"{subpath}{fileName}").Exists)
{
//如果当前路径不以"/"作为后缀,会响应一个针对“标准”URL的重定向
if (!context.Request.Path.Value.EndsWith("/"))
{
context.Response.StatusCode = 302;
context.Response.GetTypedHeaders().Location = new Uri(path.Value + context.Request.QueryString);
return;
}
//将针对目录的URL更新为针对默认文件的URL
context.Request.Path = new PathString($"{context.Request.Path}{fileName}");
}
}
await _next(context);
}
}
正是因为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中间件如何显示默认页面
相关文章推荐
- ASP.NET Core应用针对静态文件请求的处理[4]: DirectoryBrowserMiddleware中间件如何呈现目录结构
- ASP.NET Core应用针对静态文件请求的处理[3]: StaticFileMiddleware中间件如何处理针对文件请求
- ASP.NET Core应用的错误处理[4]:StatusCodePagesMiddleware中间件如何针对响应码呈现错误页面
- ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求
- ASP.NET Core应用的错误处理[2]:DeveloperExceptionPageMiddleware中间件如何呈现“开发者异常页面”
- ASP.NET Core应用针对静态文件请求的处理[1]: 以Web的形式发布静态文件
- DefaultFilesMiddleware中间件如何显示默认页面
- C#编译器优化那点事 c# 如果一个对象的值为null,那么它调用扩展方法时为甚么不报错 webAPI 控制器(Controller)太多怎么办? .NET MVC项目设置包含Areas中的页面为默认启动页 (五)Net Core使用静态文件 学习ASP.NET Core Razor 编程系列八——并发处理
- ASP.NET Core应用的错误处理[3]:ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”
- 学习ASP.NET Core,你必须知道“中间件”是什么?中间件如何注册?请求处理管道是如何通过中间件构建的?
- 解析如何利用一个ASP.NET Core应用来发布静态文件
- StaticFileMiddleware中间件如何处理针对文件请求
- 学习ASP.NET Core, 怎能不了解请求处理管道[4]: 应用的入口——Startup
- IIS7上部署Asp.Net4.0时的若干问题--请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理
- ASP.NET Core 1.1 静态文件、路由、自定义中间件、身份验证简介
- ASP.NET Core真实管道详解[2]:Server是如何完成针对请求的监听、接收与响应的【上】
- IIS配置asp.net网站出现错误:请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理
- 学习ASP.NET Core,怎能不了解请求处理管道[1]: 中间件究竟是个什么东西?
- ASP.NET Core应用的错误处理[1]:三种呈现错误页面的方式
- 在ASP.NET 2.0中,有时候需要对ASP.NET生成的HTML代码进行处理,或者是保存成静态文件。ASP.NET 提供了直接将请求保存成文件的方法:HttpRequest.SaveAs方法。下面这个方法就是在ASP.NET 2.0中得到ASP.NET