ASP.NET Core file system

 

What is a static file?

Let’s take a look at the following example (a picture of the website was accessed via the url path in the client browser), Such a picture is a static file

ASPNET-Core-File-System2

Static files (staticfiles) actually refer to

  • fixed files like HTML,CSS,images,and JavaScript
    . They are resources that are directly provided to the client by the application.
  • Static files are usually located under the web root (content root or web root) folder.
  • Static files can be saved in any folder under the web root (default is wwwroot) and accessed through a relative root path.
    For example, when you create a default web application (MVC) project through Visual Studio,
    there will be several more folders in the wwwroot directory: css, images, and js. 

    ASPNET-Core-File-System4

     

    You can directly access the image in the images directory by using the following URL:

    http://<app>/images/<imageFileName>

Static file middleware

In the above example, in order to be able to use a static file service, you must configure the middleware to add the static file middleware to the request pipeline.
(The default created MVC web application is already configured.)

Static file middleware can be configured by adding the MicrosoftAspNetCore.StaticFiles
package dependency to the project and then calling the app.UseStaticFiles extension method from
Startup.Configure:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles();
} 

Above we use app.UseStaticFiles() to use the file middleware through a simple example , so that all static files in the web root directory are directly published.
If the static files we need to publish are stored in other directories?
Still the application, now we put the static files in the
custom folder MyStaticFiles and will publish them as a web,
showing how to use the
UseStaticFiles to
serve other non-wwwroot directories.

ASPNET-Core-File-System6

If you want to access the test.png image in the MyStaticFiles folder, you can configure the static file middleware like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles();
    app.UseStaticFiles(new StaticFileOptions() // 使用 StaticFileOptions 这个对象来初始化静态文件中间件
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")), // 物理文件路径
        RequestPath = new PathString("/StaticFiles"), // 请求路径
    });
}

ASP.NET Core generally uses a FileProvider object to read a file, and it is no exception to handle requests for static files.

The above code is in the static file middleware, calling the static file middleware method UseStaticFiles().
This method can accept a configuration item object StaticFileOptions, which internally has a mapping relationship between FileProvider and request path.

If the UseStaticFiles method is called without specifying any parameters,
the request path of the mapping relationship is the application’s base address (PathBase),
and the FileProvider is naturally the PhysicalFileProvider pointing to the WebRoot directory.

You can access the test.png image file by visiting http://<app>/StaticFiles/test.png.

Static file authorization:

Static file middleware does not provide authorization checking by default.
Any files provided through this module, including files under wwwroot, are public, so how do you give them authorization?

Save the file outside of wwwroot, set the directory to be accessible by the static file middleware, and access it through a controller action. After authorization, return HleResulU to save the file outside of wwwroot and set the directory to be The static file middleware is accessed, accessed through an itrolleraction, and returned to FileResult after authorization.

Directory browsing

The above registered StaticFileMiddleware will only process requests for a specific static file. If we send an HTTP request to the URL of a directory, we will get a response with a status of 404.
That’s because, for security reasons, the application disables directory access by default.
Directory browsing is to allow website users to see a list of directories and files in the specified directory.
We can display the contents of the request directory by registering a middleware called DirectoryBrowserMiddleware:

Step1.
Add the directory browsing service by calling the AddDirectoryBrowser extension method in
Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

Step2.

Then use the UseDirectoryBrowser extension method in Startup.Configure to use the middleware to open the web application directory browsing:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseStaticFiles();
    
    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles"),
    });
    
    app.UseDirectoryBrowser(new DirectoryBrowserOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles"),
    });
}

After running the program, you can browse the directories in the ContentRoot/StaticFiles folder by going to http:<app>/StaticFiles.
This middleware will return an HTML page, and all the files in the request directory will be included in this page in the form of a table (including every folder and file under the folder)

Note: Use a static file  and directory browsing difference between the Step2.
Startup.Configure method calls two app.UseStaticFiles
: static files allow the first call request wwwroot folder, the second call is allowed to pass through http :<app>/StaticFiles/<fileName> Requests a static file in the StaticFiles folder. Calling app.UseDirectoryBrowser
is a directory that allows browsing of the StaticFiles folder via http:<app>/StaticFiles
.

Register to browse the specified directory

The app.UseDirectoryBrowser method accepts a configuration item object, DirectoryBrowserOptions, which is similar to the static file middleware configuration item object, which allows you to configure the directory and the requested virtual path that the user is allowed to browse

Default file

Setting a default home page provides a default start page for each visitor to the site.
In order to enable the site to provide a default page and avoid the user entering the full URL, we can
call the app.UseDefaultFiles extension method in Startup.Configure:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseDefaultFiles();
    app.UseStaticFiles();
}

app.UseDefaultFiles must be called before UseStaticFiles.
UseDefaultFiles just rewrote the URL instead of actually providing such a file.
Therefore you must open the static file middleware (UseStaticFiles) to provide this file.

With UseDefanltFiles, the following files will be retrieved when the folder is requested:

  • Default.htm
  • Default.html
  • Index.htm
  • Index.html

The first file found in the list will be returned to the user as a response to the request for the full URL, at which point the URL on the browser will continue to display the URI entered by the user.

Specify default file

The static file middleware can accept a configuration object parameter of DefaultFilesOptions. By adding the default home page name, you can specify a custom default file (the default home page). The following code shows how to change the default file name to myindex.html.

public void Configure(IApplicationBuilder app)
{
	DefaultFilesOptions options = new DefaultFilesOptions();
	options.DefaultFileNames.Clear(); // 
	options.DefaultFileNames.Add("login.html"); //
	app.UseDefaultFiles(options); //
	app.UseStaticFiles();     //
}

Add the login.html page to the web root directory and run the program:

 

UseFileServer

UseFileServer is a collection of UseStaticFiles,UseDefaultFiles ,and UseDirectoryBrowser.

The following code enables static files and default files, but does not allow direct access to the directory:

app.UseFileServer();

The following code enables static files, default files, and directory browsing:

app.UseFileServer(enableDirectoryBrowsing:true);

As a way to combine the UseStaticFiles,UseDefaultFiles,and UseDirectoryBrowser methods, if you want to provide files that exist outside of the web root, you need to instantiate and configure a FileServerOptions
object to pass to the app.UscFileServer parameters.
For example, there are directories in the application that have the following levels:

 

ASPNET-Core-File-System10

For the example above, you might want to enable static files, default files, and browse the MyStaticFiles directory.
The following code snippet demonstrates how to fully implement these functions by calling FileServerOptions
once:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseFileServer(new FileServerOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles"),
        EnableDirectoryBrowsing = true,
        EnableDefaultFiles = true,
    });
}

If you set enableDirectoryBrowsing to true, you must call the services.AddDirectoryBrowser extension method
in Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDirectoryBrowser();
}

If there is a default page under the MyStaticFiles directory, the default page opens.
If there is no file named by default, http://StaticFiles will return a directory listing of the directory StaticFiles, as shown in the following figure.

 

FileExtensionContentTypeProvider

The FileExtensionContentTypeProvider class contains a collection that maps file extensions to MIME content types.In the following example, multiple file extensions (eg: .myapp) are registered as known MIME types (application/x-msdownload), “.rtf” is replaced, and “.mp4” is removed:

public void Configure(IApplicationBuilder app)
{
    FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
    // add new mapping.
    provider.Mappings[".myapp"] = "application/x-msdownload";
    provider.Mappings[".htm3"] = "text/html";
    provider.Mappings[".image"] = "image/png";

    // replace an existing mepping.
    provider.Mappings[".rtf"] = "application/x-msdownload";

    // remove mp4 vidios.
    provider.Mappings.Remove(".mp4");
    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles"),
        ContentTypeProvider = provider,
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles"),
    });
}

 

Non-standard content type


ASP.NET
 Core static file middleware can support more than 400 known file content types.
If the user requests an unknown file type, the static file middleware will return an HTTP 404 (not found) response.
If directory browsing is enabled, the URL of the file will be displayed, but the access URL will return an HTTP404 error.
The following is the code to treat unrecognized types and files as downloaded files:

public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles"),
        ServeUnknownFileTypes = true,
        DefaultContentType = "application/x-msdownload",
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions()
    {
        FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "MyStaticFiles")),
        RequestPath = new PathString("/StaticFiles"),
    });

}

Precautions:

  • UseDirectoryBrowser and UseStaticFiles may be compromised.
    It is not recommended to open directory browsing in a production environment.
    Be careful with directories where you have enabled UseStaticFiles or UseDirectoryBrowser, and their subfiles and subdirectories are accessible.
    It is recommended to keep the public content in a directory such as <content root>/wwwroot, away from application views, configuration files, and so on.
  • The URLs of files exposed using UseDirectoryBrowser and UseStaticFiles are case sensitive and character constrained, subject to the underlying file system.
    For example, Windows is not case sensitive, but MACOS and Linux are case sensitive.

 

Practical simple file server

1 First create a new ASP.NETCore project and select an empty template.

2 Add a Microsoft.AspNetCore.StaticFiles reference using the NuGet command:

Install-PackageMicrosoft.AspNetCore.StaticFiles

3 If our file server needs to be able to access and browse all the files and folders of the E drive, then we need to use the UseStaticFiles and UseDirectoryBrowser methods, add the following code under the Startup.Configure
method:

public void Configure(IApplicationBuilder app)
{
    FileExtensionContentTypeProvider provider = new FileExtensionContentTypeProvider();
    provider.Mappings[".log"] = "text/plain";
    app.UseStaticFiles(new StaticFileOptions()
    {
        FileProvider = new PhysicalFileProvider(@"E:\"),  
        ServeUnknownFileTypes = true,
        ContentTypeProvider = provider,
        DefaultContentType = "application/x-msdownload", 
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions()
    {
        FileProvider = new PhysicalFileProvider(@"E:\"), 
    });
}

In this way, we can browse all the files and folders of the server E disk through the client.
We also manually set a default value for the unrecognized MIME type (“application/x-msdownload”), which will be downloaded when the browser opens these unrecognized types of files. Files like .log are manually set to text and the browser will display them directly. This way we have implemented a simple file server.

If you want to view images or video files from other computers or mobile phones on the LAN, you can modify the application URL in the launchSettings.json configuration file in the Properties file:

"WebApplication": {
  "commandName": "Project",
  "launchBrowser": true,
  "applicationUrl": "https://*:5001;http://*:5000",  
  "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development"
  }
}

In this way, in the same LAN, accessing http:ip:5000 on the mobile phone, you can access the files in the server E disk.

 

Reference original


Microsoft Documentation ASP.NET Core Middleware