Skip to content

Commit 4b27114

Browse files
Add MapStaticFIles to TOC and rename files (#34979)
* Add MapStaticFIles to TOC and rename files * Add MapStaticFIles to TOC and rename files
1 parent 290a862 commit 4b27114

4 files changed

Lines changed: 211 additions & 209 deletions

File tree

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
---
2+
title: Map static files in ASP.NET Core
3+
author: rick-anderson
4+
description: Learn how to serve and secure mapped static files and configure static file hosting middleware behaviors in an ASP.NET Core web app.
5+
monikerRange: '>= aspnetcore-8.0'
6+
ms.author: riande
7+
ms.custom: mvc
8+
ms.date: 3/18/2025
9+
uid: fundamentals/map-static-files
10+
---
11+
12+
# Map static files in ASP.NET Core
13+
14+
:::moniker range=">= aspnetcore-9.0"
15+
16+
By [Rick Anderson](https://twitter.com/RickAndMSFT)
17+
18+
Static files, such as HTML, CSS, images, and JavaScript, are assets an ASP.NET Core app serves directly to clients by default.
19+
20+
For Blazor static files guidance, which adds to or supersedes the guidance in this article, see <xref:blazor/fundamentals/static-files>.
21+
22+
## Serve static files
23+
24+
Static files are stored within the project's [web root](xref:fundamentals/index#web-root) directory. The default directory is `{content root}/wwwroot`, but it can be changed with the <xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseWebRoot%2A> method. For more information, see [Content root](xref:fundamentals/index#content-root) and [Web root](xref:fundamentals/index#web-root).
25+
26+
The <xref:Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder%2A> method sets the content root to the current directory:
27+
28+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet&highlight=1,15)]
29+
30+
Static files are accessible via a path relative to the [web root](xref:fundamentals/index#web-root). For example, the **Web Application** project templates contain several folders within the `wwwroot` folder:
31+
32+
* `wwwroot`
33+
* `css`
34+
* `js`
35+
* `lib`
36+
37+
Consider an app with the `wwwroot/images/MyImage.jpg` file. The URI format to access a file in the `images` folder is `https://<hostname>/images/<image_file_name>`. For example, `https://localhost:5001/images/MyImage.jpg`
38+
39+
### MapStaticAssets
40+
41+
Creating performant web apps requires optimizing asset delivery to the browser. Possible optimizations include:
42+
43+
* Serve a given asset once until the file changes or the browser clears its cache. Set the [ETag](https://developer.mozilla.org/docs/Web/HTTP/Headers/ETag) header.
44+
* Prevent the browser from using old or stale assets after an app is updated. Set the [Last-Modified](https://developer.mozilla.org/docs/Web/HTTP/Headers/Last-Modified) header.
45+
* Set up proper [caching headers](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control).
46+
* Use [caching middleware](xref:performance/caching/middleware).
47+
* Serve [compressed](/aspnet/core/performance/response-compression) versions of the assets when possible.
48+
* Use a [CDN](/microsoft-365/enterprise/content-delivery-networks?view=o365-worldwide&preserve-view=true) to serve the assets closer to the user.
49+
* Minimize the size of assets served to the browser. This optimization doesn't include minification.
50+
51+
<xref:Microsoft.AspNetCore.Builder.StaticAssetsEndpointRouteBuilderExtensions.MapStaticAssets%2A>:
52+
* Integrates the information gathered about static web assets during the build and publish process with a runtime library that processes this information to optimize file serving to the browser.
53+
* Are routing endpoint conventions that optimize the delivery of static assets in an app. It's designed to work with all UI frameworks, including Blazor, Razor Pages, and MVC.
54+
55+
### `MapStaticAssets` versus `UseStaticFiles`
56+
57+
<xref:Microsoft.AspNetCore.Builder.StaticAssetsEndpointRouteBuilderExtensions.MapStaticAssets%2A> is available in ASP.NET Core in .NET 9.0 and later. <xref:Microsoft.AspNetCore.Builder.StaticFileExtensions.UseStaticFiles%2A> must be used in versions prior to .NET 9.0.
58+
59+
<xref:Microsoft.AspNetCore.Builder.StaticFileExtensions.UseStaticFiles%2A> serves static files, but it doesn't provide the same level of optimization as `MapStaticAssets`. `MapStaticAssets` is optimized for serving assets that the app has knowledge of at runtime. If the app serves assets from other locations, such as disk or embedded resources, `UseStaticFiles` should be used.
60+
61+
The following features are supported in `UseStaticFiles` but not in `MapStaticAssets`:
62+
63+
* [Serving files from disk or embedded resources, or other locations](xref:fundamentals/static-files#serve-files-from-multiple-locations)
64+
* [Serve files outside of web root](xref:fundamentals/static-files#serve-files-outside-of-web-root)
65+
* [Set HTTP response headers](xref:fundamentals/static-files#set-http-response-headers)
66+
* [Directory browsing](xref:fundamentals/static-files#directory-browsing)
67+
* [Serve default documents](xref:fundamentals/static-files#serve-default-documents)
68+
* [`FileExtensionContentTypeProvider`](xref:fundamentals/static-files#fileextensioncontenttypeprovider)
69+
* [Serve files from multiple locations](xref:fundamentals/static-files#serve-files-from-multiple-locations)
70+
* [Serving files from disk or embedded resources, or other locations](xref:fundamentals/static-files#serve-files-from-multiple-locations)
71+
* [Serve files outside of web root](xref:fundamentals/static-files#serve-files-outside-of-web-root)
72+
* [Set HTTP response headers](xref:fundamentals/static-files#set-http-response-headers)
73+
* [Directory browsing](xref:fundamentals/static-files#directory-browsing)
74+
* [Serve default documents](xref:fundamentals/static-files#serve-default-documents)
75+
* [`FileExtensionContentTypeProvider`](xref:fundamentals/static-files#fileextensioncontenttypeprovider)
76+
* [Serve files from multiple locations](xref:fundamentals/static-files#serve-files-from-multiple-locations)
77+
78+
### Serve files in web root
79+
80+
The default web app templates call the <xref:Microsoft.AspNetCore.Builder.StaticAssetsEndpointRouteBuilderExtensions.MapStaticAssets%2A> method in `Program.cs`, which enables static files to be served:
81+
82+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet&highlight=15)]
83+
84+
The parameterless `MapStaticAssets` method overload marks the files in [web root](xref:fundamentals/index#web-root) as servable. The following markup references `wwwroot/images/MyImage.jpg`:
85+
86+
```html
87+
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
88+
```
89+
90+
In the preceding markup, the tilde character `~` points to the [web root](xref:fundamentals/index#web-root).
91+
92+
### Serve files outside of web root
93+
94+
Consider a directory hierarchy in which the static files to be served reside outside of the [web root](xref:fundamentals/index#web-root):
95+
96+
* `wwwroot`
97+
* `css`
98+
* `images`
99+
* `js`
100+
* `MyStaticFiles`
101+
* `images`
102+
* `red-rose.jpg`
103+
104+
A request can access the `red-rose.jpg` file by configuring the Static File Middleware as follows:
105+
106+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_rr&highlight=1,18-23)]
107+
108+
In the preceding code, the *MyStaticFiles* directory hierarchy is exposed publicly via the *StaticFiles* URI segment. A request to `https://<hostname>/StaticFiles/images/red-rose.jpg` serves the `red-rose.jpg` file.
109+
110+
The following markup references `MyStaticFiles/images/red-rose.jpg`:
111+
<!-- zz test via /Home2/MyStaticFilesRR -->
112+
[!code-html[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Views/Home2/MyStaticFilesRR.cshtml?range=1)]
113+
114+
To serve files from multiple locations, see [Serve files from multiple locations](xref:fundamentals/static-files#serve-files-from-multiple-locations).
115+
116+
### Set HTTP response headers
117+
118+
A <xref:Microsoft.AspNetCore.Builder.StaticFileOptions> object can be used to set HTTP response headers. In addition to configuring static file serving from the [web root](xref:fundamentals/index#web-root), the following code sets the [Cache-Control](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control) header:
119+
120+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_rh&highlight=16-24)]
121+
122+
The preceding code makes static files publicly available in the local cache for one week.
123+
124+
## Static file authorization
125+
126+
The ASP.NET Core templates call <xref:Microsoft.AspNetCore.Builder.StaticAssetsEndpointRouteBuilderExtensions.MapStaticAssets%2A> before calling <xref:Microsoft.AspNetCore.Builder.AuthorizationAppBuilderExtensions.UseAuthorization%2A>. Most apps follow this pattern. When `MapStaticAssets` is called before the authorization middleware:
127+
128+
* No authorization checks are performed on the static files.
129+
* Static files served by the Static File Middleware, such as those under `wwwroot`, are publicly accessible.
130+
131+
To serve static files based on authorization, see [Static file authorization](xref:fundamentals/static-files#static-file-authorization).
132+
133+
## Serve files from multiple locations
134+
135+
Consider the following Razor page which displays the `/MyStaticFiles/image3.png` file:
136+
137+
[!code-cshtml[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Pages/Test.cshtml?highlight=5)]
138+
139+
`UseStaticFiles` and `UseFileServer` default to the file provider pointing at `wwwroot`. Additional instances of `UseStaticFiles` and `UseFileServer` can be provided with other file providers to serve files from other locations. The following example calls `UseStaticFiles` twice to serve files from both `wwwroot` and `MyStaticFiles`:
140+
141+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_mul)]
142+
143+
Using the preceding code:
144+
145+
* The `/MyStaticFiles/image3.png` file is displayed.
146+
* The [Image Tag Helpers](xref:mvc/views/tag-helpers/builtin-th/image-tag-helper) <xref:Microsoft.AspNetCore.Mvc.TagHelpers.ImageTagHelper.AppendVersion> is not applied because the Tag Helpers depend on <xref:Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootFileProvider>. `WebRootFileProvider` has not been updated to include the `MyStaticFiles` folder.
147+
148+
The following code updates the `WebRootFileProvider`, which enables the Image Tag Helper to provide a version:
149+
150+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_mult2)]
151+
152+
> [!NOTE]
153+
> The preceding approach applies to Razor Pages and MVC apps. For guidance that applies to Blazor Web Apps, see <xref:blazor/fundamentals/static-files#serve-files-from-multiple-locations>.
154+
155+
## Serve files outside wwwroot by updating IWebHostEnvironment.WebRootPath
156+
157+
When <xref:Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootPath%2A?displayProperty=nameWithType> is set to a folder other than `wwwroot`:
158+
159+
* In the development environment, static assets found in both `wwwroot` and the updated `IWebHostEnvironment.WebRootPath` are served from `wwwroot`.
160+
* In any environment other than development, duplicate static assets are served from the updated `IWebHostEnvironment.WebRootPath` folder.
161+
162+
Consider a web app created with the empty web template:
163+
164+
* Containing an `Index.html` file in `wwwroot` and `wwwroot-custom`.
165+
* With the following updated `Program.cs` file that sets `WebRootPath = "wwwroot-custom"`:
166+
167+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/WebRoot/Program.cs?name=snippet1)]
168+
169+
In the preceding code, requests to `/`:
170+
171+
* In the development environment return `wwwroot/Index.html`
172+
* In any environment other than development return `wwwroot-custom/Index.html`
173+
174+
To ensure assets from `wwwroot-custom` are returned, use one of the following approaches:
175+
176+
* Delete duplicate named assets in `wwwroot`.
177+
* Set `"ASPNETCORE_ENVIRONMENT"` in `Properties/launchSettings.json` to any value other than `"Development"`.
178+
* Completely disable static web assets by setting `<StaticWebAssetsEnabled>false</StaticWebAssetsEnabled>` in the project file. ***WARNING, disabling static web assets disables [Razor Class Libraries](xref:razor-pages/ui-class)***.
179+
* Add the following XML to the project file:
180+
181+
```xml
182+
<ItemGroup>
183+
<Content Remove="wwwroot\**" />
184+
</ItemGroup>
185+
```
186+
187+
The following code updates `IWebHostEnvironment.WebRootPath` to a non development value, guaranteeing duplicate content is returned from `wwwroot-custom` rather than `wwwroot`:
188+
189+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/WebRoot/Program.cs?name=snippet2&highlight=5)]
190+
191+
## Additional resources
192+
193+
* [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/static-files/samples) ([how to download](xref:index#how-to-download-a-sample))
194+
* [Middleware](xref:fundamentals/middleware/index)
195+
* [Introduction to ASP.NET Core](xref:index)
196+
* <xref:blazor/file-uploads>
197+
* <xref:blazor/file-downloads>
198+
199+
:::moniker-end

0 commit comments

Comments
 (0)