ASP.NET Core (Microsoft documentation)

Posted by mackevin on Mon, 10 Jan 2022 07:12:59 +0100

By default, static files such as HTML, CSS, images, and JavaScript are ASP Net core application is an asset directly provided to the client.

View or download sample code(How to download)

Provide static files

Static files are stored in the project Web root In the directory. The default directory is {content root}/wwwroot, but you can use the UseWebRoot Method to change the directory. For more information, see Content root And Web root.

Adopt CreateDefaultBuilder Method to set the content root directory to the current directory:

C # replication
 
public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

The above code was created using a Web application template.

Can pass Web root To access the static file. For example, the Web application project template contains multiple folders in the wwwroot folder:

  • wwwroot
    • css
    • js
    • lib

Consider creating the wwwroot/images folder and adding the wwwroot/images/MyImage file. The URI format used to access the files in the images folder is HTTPS: / / < hostname > / images / < image_ file_ name>. For example, https://localhost:5001/images/MyImage.jpg

Provide files in the Web root directory

The default Web application template is in startup Call in Configure UseStaticFiles Method, which allows you to provide static files:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

No arguments. The {UseStaticFiles} method will be overloaded Web root Files in are marked as available. The following tags refer to wwwroot / images / myimage jpg:

HTML copy
 
<img src="~/images/MyImage.jpg" class="img" alt="My image" />

In the above code, the waveform symbol ~ / points to Web root.

Provide files outside the Web root directory

Consider a directory hierarchy in which the static files to be provided are located Web root outside:

  • wwwroot
    • css
    • images
    • js
  • MyStaticFiles
    • images
      • red-rose.jpg

After configuring the static file middleware as follows, the request can access {red rose JPG file:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    // using Microsoft.Extensions.FileProviders;
    // using System.IO;
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.ContentRootPath, "MyStaticFiles")),
        RequestPath = "/StaticFiles"
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

In the previous code, the MyStaticFiles directory hierarchy is exposed through the StaticFiles URI segment. HTTPS: / / < hostname > / staticfiles / images / red rose Jpg's request will provide red rose JPG file.

The following tags refer to mystaticfiles / images / red rose jpg:

HTML copy
 
<img src="~/StaticFiles/images/red-rose.jpg" class="img" alt="A red rose" />

Set HTTP response header

StaticFileOptions Object can be used to set the HTTP response header. Except configuration from Web root In addition to providing static files, the following code also sets the cache control header:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    const string cacheMaxAge = "604800";
    app.UseStaticFiles(new StaticFileOptions
    {
        OnPrepareResponse = ctx =>
        {
            // using Microsoft.AspNetCore.Http;
            ctx.Context.Response.Headers.Append(
                 "Cache-Control", $"public, max-age={cacheMaxAge}");
        }
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

Static files can be publicly cached in 600 seconds:

Static file authorization

ASP.NET Core template calling UseAuthorization Previous call UseStaticFiles . Most applications follow this pattern. If you call a static file middleware before you authorize the middleware,

  • No authorization checks are performed on static files.
  • The static files provided by the static file middleware (such as the files under "wwwroot") can be accessed publicly.

Provide static files as authorized:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    // wwwroot css, JavaScript, and images don't require authentication.
    app.UseStaticFiles();   

    app.UseRouting();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
                     Path.Combine(env.ContentRootPath, "MyStaticFiles")),
        RequestPath = "/StaticFiles"
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}
C # replication
 
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));
        services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
            .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddRazorPages();

        services.AddAuthorization(options =>
        {
            options.FallbackPolicy = new AuthorizationPolicyBuilder()
                .RequireAuthenticatedUser()
                .Build();
        });
    }

    // Remaining code ommitted for brevity.

In the previous code, the fallback authorization policy requires all users to authenticate. Endpoints that specify their own authorization requirements (such as controllers, Razor Pages, etc.) do not use fallback authorization policies. For example, Razor Pages, controllers, or operation methods with [AllowAnonymous] or [Authorize(PolicyName="MyPolicy")] use the authorization attributes of the application rather than fallback the authorization policy.

RequireAuthenticatedUser Will DenyAnonymousAuthorizationRequirement Add to the current instance, which will force authentication of the current user.

The static assets under wwwroot , are publicly accessible because the default static file middleware (app.UseStaticFiles();) will be called before , UseAuthentication ,. Static assets in the MyStaticFiles folder require authentication.   Sample code This was demonstrated.

Another way to provide documents under authorization is:

  • Store the files outside of any directory accessible to {wwwroot} and static file middleware.
  • Provide services for it by applying authorized operation methods, and return FileResult Object:
C # replication
 
[Authorize]
public IActionResult BannerImage()
{
    var filePath = Path.Combine(
        _env.ContentRootPath, "MyStaticFiles", "images", "red-rose.jpg");

    return PhysicalFile(filePath, "image/jpeg");
}

directory browse

Directory browsing allows you to list directories in a specified directory.

For security reasons, directory browsing is disabled by default. For more information, see Security considerations for static files.

Enable directory browsing by:

C # replication
 
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddDirectoryBrowser();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    // using Microsoft.Extensions.FileProviders;
    // using System.IO;
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.WebRootPath, "images")),
        RequestPath = "/MyImages"
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.WebRootPath, "images")),
        RequestPath = "/MyImages"
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

The above code allows you to use the URL HTTPS: / / < hostname > / myimages to browse the directory of the wwwroot/images folder and link to each file and folder:

Provide default document

Set the default page to provide visitors with the starting point of the site. To provide a default file from {wwwroot} without requiring the request URL to contain a file name, call UseDefaultFiles Method:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    app.UseDefaultFiles();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

To provide default files, you must call UseDefaultFiles before UseStaticFiles. Usedefaultfiles} is a URL rewriting tool that does not provide files.

To request a search for a folder in {wwwroot} using {UseDefaultFiles}:

  • default.htm
  • default.html
  • index.htm
  • index.html

As if the request contained a file name, provide the first file found from the list. The browser URL continues to reflect the requested URI.

The following code changes the default file name to mydefault html:

C # replication
 
var options = new DefaultFilesOptions();
options.DefaultFileNames.Clear();
options.DefaultFileNames.Add("mydefault.html");
app.UseDefaultFiles(options);
app.UseStaticFiles();

The following code demonstrates} startup through the above code Configure:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    var options = new DefaultFilesOptions();
    options.DefaultFileNames.Clear();
    options.DefaultFileNames.Add("mydefault.html");
    app.UseDefaultFiles(options);
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

UseFileServer for default documents

UseFileServer It combines the functions of , UseStaticFiles , UseDefaultFiles , and , UseDirectoryBrowser (optional).

Call app UseFileServer to provide static files and default files. Directory browsing is not enabled. The following code demonstrates {startup. Exe} through {UseFileServer} Configure:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    app.UseFileServer();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

The following code provides static file, default file, and directory browsing:

C # replication
 
app.UseFileServer(enableDirectoryBrowsing: true);

The following code demonstrates} startup through the above code Configure:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    app.UseFileServer(enableDirectoryBrowsing: true);

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

Consider the following directory hierarchy:

  • wwwroot
    • css
    • images
    • js
  • MyStaticFiles
    • images
      • MyImage.jpg
    • default.html

The following code provides directory browsing of static files, default files, and MyStaticFiles:

C # replication
 
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews();
    services.AddDirectoryBrowser();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    app.UseStaticFiles(); // For the wwwroot folder.

    // using Microsoft.Extensions.FileProviders;
    // using System.IO;
    app.UseFileServer(new FileServerOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.ContentRootPath, "MyStaticFiles")),
        RequestPath = "/StaticFiles",
        EnableDirectoryBrowsing = true
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

Must be called when the value of the {EnableDirectoryBrowsing} property is {true} AddDirectoryBrowser.

Using the file hierarchy and the previous code, the URL is resolved as follows:

Table 1
URIresponse
https://<hostname>/StaticFiles/images/MyImage.jpg MyStaticFiles/images/MyImage.jpg
https://<hostname>/StaticFiles MyStaticFiles/default.html

If the default named file does not exist in the MyStaticFiles directory, HTTPS: / / < hostname > / staticfiles returns a list of directories containing clickable links:

UseDefaultFiles And UseDirectoryBrowser Perform client redirection from the target URI with tail / to the target URI with tail /. For example, from HTTPS: / / < hostname > / StaticFiles to HTTPS: / / < hostname > / StaticFiles /. The relative URL in the StaticFiles directory is invalid without a trailing slash (/).

FileExtensionContentTypeProvider

FileExtensionContentTypeProvider Class contains the Mappings property, which is used as a mapping of file extensions to mime content types. In the following example, multiple file extensions are mapped to known MIME types. Replaced rtf extension, deleted mp4 :

C # replication
 
// using Microsoft.AspNetCore.StaticFiles;
// using Microsoft.Extensions.FileProviders;
// using System.IO;

// Set up custom content types - associating file extension to MIME type
var provider = new FileExtensionContentTypeProvider();
// Add new mappings
provider.Mappings[".myapp"] = "application/x-msdownload";
provider.Mappings[".htm3"] = "text/html";
provider.Mappings[".image"] = "image/png";
// Replace an existing mapping
provider.Mappings[".rtf"] = "application/x-msdownload";
// Remove MP4 videos.
provider.Mappings.Remove(".mp4");

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/MyImages",
    ContentTypeProvider = provider
});

app.UseDirectoryBrowser(new DirectoryBrowserOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(env.WebRootPath, "images")),
    RequestPath = "/MyImages"
});

The following code demonstrates} startup through the above code Configure:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    // using Microsoft.AspNetCore.StaticFiles;
    // using Microsoft.Extensions.FileProviders;
    // using System.IO;

    // Set up custom content types - associating file extension to MIME type
    var provider = new FileExtensionContentTypeProvider();
    // Add new mappings
    provider.Mappings[".myapp"] = "application/x-msdownload";
    provider.Mappings[".htm3"] = "text/html";
    provider.Mappings[".image"] = "image/png";
    // Replace an existing mapping
    provider.Mappings[".rtf"] = "application/x-msdownload";
    // Remove MP4 videos.
    provider.Mappings.Remove(".mp4");

    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.WebRootPath, "images")),
        RequestPath = "/MyImages",
        ContentTypeProvider = provider
    });

    app.UseDirectoryBrowser(new DirectoryBrowserOptions
    {
        FileProvider = new PhysicalFileProvider(
            Path.Combine(env.WebRootPath, "images")),
        RequestPath = "/MyImages"
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

See MIME content type.

Non standard content types

The static file middleware can understand nearly 400 known file content types. If the user requests a file with unknown file type, the static file middleware passes the request to the next Middleware in the pipeline. If no middleware processes the request, a "404 not found" response is returned. If directory browsing is enabled, a link to the file is displayed in the directory list.

The following code provides an unknown type and renders the unknown file as an image:

C # replication
 
app.UseStaticFiles(new StaticFileOptions
{
    ServeUnknownFileTypes = true,
    DefaultContentType = "image/png"
});

The following code demonstrates} startup through the above code Configure:

C # replication
 
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();

    app.UseStaticFiles(new StaticFileOptions
    {
        ServeUnknownFileTypes = true,
        DefaultContentType = "image/png"
    });

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapDefaultControllerRoute();
    });
}

Using the previous code, when the requested file contains an unknown content type, the request is returned as an image.

Warning

Enable ServeUnknownFileTypes It will form a potential safety hazard. It is disabled by default and is not recommended.   FileExtensionContentTypeProvider Provides a more secure alternative to providing files with non-standard extensions.

Provide files from multiple locations

UseStaticFiles , and , UseFileServer , are file providers pointing to , wwwroot , by default. You can use other file providers to provide other instances of {UseStaticFiles} and {UseFileServer} to provide files from multiple locations. For more information, see This GitHub problem.

Security considerations for static files

Warning

UseDirectoryBrowser , and , UseStaticFiles , may disclose secrets. It is strongly recommended that directory browsing be disabled in production. Please carefully check which directories are enabled by {UseStaticFiles} or {UseDirectoryBrowser}. The entire directory and its subdirectories are publicly accessible. Store files suitable for disclosure in a private directory, such as < content_ root>/wwwroot. Separate these files from MVC views, Razor Pages, configuration files, and so on.

  • The URL of content exposed using , UseDirectoryBrowser , and , UseStaticFiles , is affected by case and underlying file system character restrictions. For example, Windows is not case sensitive, but Mac OS and Linux are case sensitive.

  • Asp.net hosted in IIS Net core application usage ASP.NET Core module Forward all requests to the application, including static file requests. IIS static file handlers are not used and there is no opportunity to process requests.

  • Complete the following steps in IIS Manager to remove IIS static file handlers at the server or web site level:

    1. Go to the module function.
    2. Select StaticFileModule from the list.
    3. Click delete in the actions sidebar.

Warning

If IIS static file handler is enabled and ASP If the net core module is not configured correctly, a static file will be provided. For example, if you do not deploy web Config file.

  • Place the code files (including. cs and. cshtml) in the application project Web root outside. This creates a logical separation between the client content of the application and the server based code. It can prevent server-side code leakage.

Topics: .NET