How Directorybrowsermiddleware middleware renders the directory structure

Source: Internet
Author: User


How Directorybrowsermiddleware middleware renders the directory structure


Like Staticfilemiddleware middleware, Directorybrowsermiddleware essentially defines a mapping between a request address and a physical directory . The target directory is represented as a Fileprovider object. When the middleware receives a matching request, it resolves the relative path of the corresponding directory according to the request address and uses this fileprovider to get the contents of the directory. The contents of the catalog will eventually be defined as an HTML document, and this HTML will eventually be the content of the middleware response, and the implementation of the directory browser is simple. [This article has been synced to the "ASP. NET Core Framework"]


Directory
First, Directorybrowsermiddleware
Second, Directoryformatter
Third, the specific request processing logic
Iv. Custom Directoryformatter

First, Directorybrowsermiddleware


Next, let's look at the definition of directorybrowsermiddleware. As shown in the following code fragment, the second constructor for Directorybrowsermiddleware has four parameters, where the second parameter is the hostingenvironment representing the current execution environment. As the third parameter is a Htmlencoder object, when the target directory is rendered as an HTML document, it is used to implement encoding for HTML, if not explicitly specified (call the first constructor), The default Htmlencoder (Htmlencoder.default) is used. For a fourth parameter of type ioptions<directorybrowseroptions>, the configuration option for Directorybrowsermiddleware is hosted. Directorybrowseroptions, like the staticfileoptions described earlier, are subclasses of Sharedoptionsbase.


 1: public class DirectoryBrowserMiddleware
   2: {
   3:     public DirectoryBrowserMiddleware(RequestDelegate next, IHostingEnvironment env, IOptions<DirectoryBrowserOptions> options)
   4:     public DirectoryBrowserMiddleware(RequestDelegate next, IHostingEnvironment hostingEnv, HtmlEncoder encoder, IOptions<DirectoryBrowserOptions> options);
   5:     public Task Invoke(HttpContext context);
   6: }
   7:  
   8: public class DirectoryBrowserOptions : SharedOptionsBase
   9: {
  10:     public IDirectoryFormatter Formatter { get; set; }
  11:  
  12:     public DirectoryBrowserOptions();
  13:     public DirectoryBrowserOptions(SharedOptions sharedOptions);
  14: }


 Second, Directoryformatter 


The purpose of the Directorybrowsermiddleware middleware is to explicitly format the content (Files and subdirectories) in a directory into a readable form to respond to the client . The response to the contents of the catalog is ultimately implemented on a Directoryformatter object. Directoryformatter is our general designation of all types and corresponding objects that implement the Idirectoryformatter interface, and the formatter property of Directorybrowseroptions is set and returned as an object.



As shown in the following code snippet, the Idirectoryformatter interface contains only a single Generatecontentasync method. When implementing this method, we can get the information of the current request context using the first parameter of type HttpContext. Another parameter of the method returns a set of FileInfo, each fileinfo representing a file or subdirectory under the target.

 1:public Interface Idirectoryformatter

 2: {

 3:     Task Generatecontentasync (HttpContext context, ienumerable<ifileinfo> contents);

 4:}


We know that by default the contents of the request directory are rendered as a table on the page, and the HTML document containing the table is generated by default using the Directoryformatter, which is an object of type Htmldirectoryformatter. As shown in the following code snippet, we need to specify a Htmlencoder object when constructing a Htmldirectoryformatter object. The object originally originated from the Htmlencoder object that was specified when the Directorybrowsermiddleware was constructed.


 
1:public class Htmldirectoryformatter:idirectoryformatter

 2: {

 3: Public     Htmldirectoryformatter (Htmlencoder encoder);

 4: Public     virtual Task Generatecontentasync (HttpContext context, ienumerable<ifileinfo> contents);

 5:}

 third, the specific request processing logic 


Since the most complex work (rendering directory content) has been handed over to Directoryformatter, Directorybrowsermiddleware's own work is actually not much. To better illustrate what the middleware is doing with the request, we have redefined the Directorybrowsermiddleware type in a way that is well understood, and the implementation is reflected in the code snippet shown below.


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: / / only GET and HEAD requests are processed
20:         if (!new string[] { "GET", "HEAD" }.Contains(context.Request.Method, StringComparer.OrdinalIgnoreCase))
21:         {
22:             await _next(context);
23:             return;
24:         }
25:
26: / / verify that the current path matches the registered request path
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: / / verify that the target directory exists
36:         IDirectoryContents directoryContents = _options.FileProvider.GetDirectoryContents(subpath);
37:         if (!directoryContents.Exists)
38:         {
39:             await _next(context);
40:             return;
41:         }
42:
43: / / if the current path does not use "/" as the suffix, it will respond to a redirection for the "standard" 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: / / respond to directory content with directoryformatter
52:         await _options.Formatter.GenerateContentAsync(context, directoryContents);
53:}
54:}


As shown in the code snippet above, when Directorybrowsermiddleware finally uses the registered Directoryformatter to respond to the contents of the target directory, it does a series of upfront work. For example, it verifies whether the current request is a GET or head request, and whether the current URL matches the registered request path and, in the case of a match, verifies that the target directory exists. In addition, the middleware requires that the request to access the directory be suffixed with the character "/", otherwise the suffix is added to the current path and a redirect is sent for the final path. So when we use the browser to send a request for a directory, the URL clearly does not specify "/" as a suffix, this suffix will automatically add to us, this is the role of redirection.


Iv. Custom Directoryformatter


Because the contents of the catalog are rendered in the browser entirely by Directoryformatter, if the default rendering in Htmldirectoryformatter does not meet the requirements (for example, we need this page to maintain the same style as the existing site), This can be done by registering a custom directoryformatter. Next we demonstrate how to define such a directoryformatter with a simple example. We named the custom Directoryformatter Listdirectoryformatter as a simple list for it to simply display all the files or subdirectories.


 1: public class ListDirectoryFormatter : IDirectoryFormatter
   2: {
   3:     public async Task GenerateContentAsync(HttpContext context, IEnumerable<IFileInfo> contents)
   4:     {
   5:         context.Response.ContentType = "text/html";
   6:         await context.Response.WriteAsync("<html><head><title>Index</title><body><ul>");
   7:         foreach (var file in contents)
   8:         {
   9:             string href = $"{context.Request.Path.Value.TrimEnd(‘/‘)}/{file.Name}";
  10:             await context.Response.WriteAsync($"<li><a href=‘{href}‘>{file.Name}</a></li>");
  11:         }
  12:         await context.Response.WriteAsync("</ul></body></html>");
  13:     }
  14: }
  15:  
  16: public class Program
  17: {
  18:     public static void Main()
  19:     {
  20:         new WebHostBuilder()
  21:             .UseContentRoot(Directory.GetCurrentDirectory())
  22:             .UseKestrel()
  23:             .Configure(app => app.UseDirectoryBrowser(new DirectoryBrowserOptions {Formatter = new ListDirectoryFormatter()}))
  24:             .Build()
  25:             .Run();
  26:     }
  27: }


 


As in the code snippet above, Listdirectoryformatter ultimately responds to a complete HTML document whose body part contains only an unordered list of <ul>...</ul> representations. A list element (<li>) is a link to a file or subdirectory. When calling the extension method usedirectorybrowser to register the Directorybrowsermiddleware middleware, We set the Formatter property to Directorybrowseroptions for a Listdirectoryformatter object. The contents of the catalog will eventually be presented in the form of 9 in the current browser.









ASP. NET core application processing for static file requests [1]: Publishing static files as Web
The processing of ASP. NET core applications for static file requests [2]: Conditional request and Interval request
The processing of ASP. NET core applications for static file requests [3]: How Staticfilemiddleware middleware handles file requests
ASP. NET core application processing for static file requests [4]: How the Directorybrowsermiddleware middleware renders the directory structure
The process of ASP. NET core application for static file request [5]: Defaultfilesmiddleware middleware How to display the default page



How Directorybrowsermiddleware middleware renders the directory structure


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.