1: public class DirectoryBrowserMiddleware
2: {
3: private RequestDelegate _next;
4: private DirectoryBrowserOptions _options;
5:
6: public DirectoryBrowserMiddleware(RequestDelegate next, IHostingEnvironment env, IOptions<DirectoryBrowserOptions> options) : this(next, env, HtmlEncoder.Default,options)
7: { }
8:
9: public DirectoryBrowserMiddleware(RequestDelegate next, IHostingEnvironment env, HtmlEncoder encoder, IOptions<DirectoryBrowserOptions> options)
10: {
11: _next = next;
12: _options = options.Value;
13: _options.FileProvider = _options.FileProvider ?? env.WebRootFileProvider;
14: _options.Formatter = _options.Formatter ?? new HtmlDirectoryFormatter(encoder);
15: }
16:
17: public async Task Invoke(HttpContext context)
18: {
19: //只处理GET和HEAD请求
20: if (!new string[] { "GET", "HEAD" }.Contains(context.Request.Method, StringComparer.OrdinalIgnoreCase))
21: {
22: await _next(context);
23: return;
24: }
25:
26: //检验当前路径是否与注册的请求路径相匹配
27: PathString path = new PathString(context.Request.Path.Value.TrimEnd('/') + "/");
28: PathString subpath;
29: if (!path.StartsWithSegments(_options.RequestPath, out subpath))
30: {
31: await _next(context);
32: return;
33: }
34:
35: //检验目标目录是否存在
36: IDirectoryContents directoryContents = _options.FileProvider.GetDirectoryContents(subpath);
37: if (!directoryContents.Exists)
38: {
39: await _next(context);
40: return;
41: }
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:
51: //利用DirectoryFormatter响应目录内容
52: await _options.Formatter.GenerateContentAsync(context, directoryContents);
53: }
54: }