using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.FileProviders;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Vit.Core.Util.Common;
using Vit.WebHost;
namespace Vit.Extensions
{
public static partial class IApplicationBuilderExtensions_UseStaticFiles
{
///
/// 启用静态文件服务
///
///
///
/// /* 映射静态文件。若不指定则不映射静态文件 */
/// "staticFiles": {
///
/// /* 请求路径(可不指定)。demo:"/file/static"。The relative request path that maps to static resources */
/// //"requestPath": "/file",
///
/// /* 静态文件路径。可为相对路径或绝对路径。若为空或空字符串则为默认路径(wwwroot)。demo:"wwwroot/demo" */
/// //"rootPath": "wwwroot",
///
/// /* 默认页面(可不指定)。An ordered list of file names to select by default. List length and ordering may affect performance */
/// //"defaultFileNames": [],
///
/// /* 是否可浏览目录(default false)。Enables directory browsing */
/// //"useDirectoryBrowser": false,
///
/// /* 静态文件类型映射配置的文件路径。可为相对路径或绝对路径。例如"contentTypeMap.json"。若不指定(或指定的文件不存在)则不指定文件类型映射配置 */
/// "contentTypeMapFile": "contentTypeMap.json",
///
/// /* 回应静态文件时额外添加的http回应头。可不指定。 */
/// "responseHeaders": {
///
/// //设置浏览器静态文件缓存3600秒
/// "Cache-Control": "public,max-age=3600"
/// }
/// }
///
///
///
///
///
///
/// 在appsettings.json文件中的路径。默认:"server.staticFiles"。
///
public static IApplicationBuilder UseStaticFilesFromConfig(this IApplicationBuilder data, string configPath = "server.staticFiles")
{
return data.UseStaticFiles(Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath(configPath));
}
///
/// 启用静态文件服务
///
///
///
/// /* 映射静态文件。若不指定则不映射静态文件 */
/// "staticFiles": {
///
/// /* 请求路径(可不指定)。demo:"/file/static"。The relative request path that maps to static resources */
/// //"requestPath": "/file",
///
/// /* 静态文件路径。可为相对路径或绝对路径。若为空或空字符串则为默认路径(wwwroot)。demo:"wwwroot/demo" */
/// //"rootPath": "wwwroot",
///
/// /* 默认页面(可不指定)。An ordered list of file names to select by default. List length and ordering may affect performance */
/// //"defaultFileNames": [],
///
/// /* 是否可浏览目录(default false)。Enables directory browsing */
/// //"useDirectoryBrowser": false,
///
/// /* 静态文件类型映射配置的文件路径。可为相对路径或绝对路径。例如"contentTypeMap.json"。若不指定(或指定的文件不存在)则不指定文件类型映射配置 */
/// "contentTypeMapFile": "contentTypeMap.json",
///
/// /* 回应静态文件时额外添加的http回应头。可不指定。 */
/// "responseHeaders": {
///
/// //设置浏览器静态文件缓存3600秒
/// "Cache-Control": "public,max-age=3600"
/// }
/// }
///
///
///
///
///
///
///
///
public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder data, StaticFilesConfig config)
{
if (config == null || data == null) return data;
#region (x.1)UseStaticFiles
var staticfileOptions = new StaticFileOptions();
//(x.x.1)requestPath
if (!string.IsNullOrEmpty(config.requestPath))
{
staticfileOptions.RequestPath = new Microsoft.AspNetCore.Http.PathString(config.requestPath);
}
#region (x.x.2)FileProvider
IFileProvider fileProvider=null;
string rootPath;
if (!string.IsNullOrWhiteSpace(rootPath=config.rootPath) && Directory.Exists(rootPath))
{
fileProvider = new PhysicalFileProvider(rootPath);
}
else if (Directory.Exists(rootPath = CommonHelp.GetAbsPath("wwwroot")))
{
fileProvider = new PhysicalFileProvider(rootPath);
}
else
{
var dir = new DirectoryInfo("wwwroot");
if(dir.Exists)
fileProvider = new PhysicalFileProvider(dir.FullName);
}
staticfileOptions.FileProvider = fileProvider;
#endregion
//(x.x.3)OnInitStaticFileOptions
config.OnInitStaticFileOptions?.Invoke(staticfileOptions);
#region (x.x.4)Response Headers
if (config.responseHeaders != null)
{
staticfileOptions.OnPrepareResponse +=
ctx =>
{
var Headers = ctx.Context.Response.Headers;
foreach (var kv in config.responseHeaders)
{
Headers[kv.Key] = kv.Value;
}
};
}
#endregion
//(x.x.5)contentTypeProvider
if (config.contentTypeProvider != null)
{
staticfileOptions.ContentTypeProvider = config.contentTypeProvider;
}
//(x.x.6)UseDefaultFiles
if (config.defaultFileNames != null)
{
data.UseDefaultFiles(new DefaultFilesOptions
{
DefaultFileNames = config.defaultFileNames,
FileProvider= fileProvider
});
}
//(x.x.7)UseStaticFiles
data.UseStaticFiles(staticfileOptions);
#endregion
//(x.2)UseDirectoryBrowser
if (config.useDirectoryBrowser == true)
{
var options = new DirectoryBrowserOptions {
RequestPath = staticfileOptions.RequestPath,
FileProvider = fileProvider,
Formatter = new SortedHtmlDirectoryFormatter()
};
data.UseDirectoryBrowser(options);
}
return data;
}
#region SortedHtmlDirectoryFormatter
///
/// 自定义DirectoryFormatter
/// https://www.cnblogs.com/artech/p/static-file-for-asp-net-core-04.html
///
///
public class SortedHtmlDirectoryFormatter : HtmlDirectoryFormatter
{
///
/// 默认按文件名称排序。 contents => contents.OrderBy(f => f.Name)
///
public Func, IEnumerable> SetOrder = contents => contents.OrderBy(f => f.Name);
public SortedHtmlDirectoryFormatter(System.Text.Encodings.Web.HtmlEncoder encoder = null) : base(encoder ?? System.Text.Encodings.Web.HtmlEncoder.Default)
{
}
public override async Task GenerateContentAsync(Microsoft.AspNetCore.Http.HttpContext context, IEnumerable contents)
{
contents = SetOrder(contents);
await base.GenerateContentAsync(context, contents);
//context.Response.ContentType = "text/html";
//await context.Response.WriteAsync("Index");
//foreach (var file in contents)
//{
// string href = $"{context.Request.Path.Value.TrimEnd('/')}/{file.Name}";
// await context.Response.WriteAsync($"- {file.Name}
");
//}
//await context.Response.WriteAsync("
");
}
}
#endregion
}
}