Skip to content

Commit 6a01f80

Browse files
authored
Map Static Assets article updates (#35780)
1 parent 38f05a0 commit 6a01f80

File tree

11 files changed

+131
-139
lines changed

11 files changed

+131
-139
lines changed

aspnetcore/fundamentals/index.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Learn the fundamental concepts for building ASP.NET Core apps, incl
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: tdykstra
77
ms.custom: mvc
8-
ms.date: 08/01/2024
8+
ms.date: 07/23/2025
99
uid: fundamentals/index
1010
---
1111
# ASP.NET Core fundamentals overview
@@ -210,9 +210,9 @@ The content root is the base path for:
210210
* Razor files (`.cshtml`, `.razor`)
211211
* Configuration files (`.json`, `.xml`)
212212
* Data files (`.db`)
213-
* The [Web root](#web-root), typically the *wwwroot* folder.
213+
* The [Web root](#web-root), typically the `wwwroot` folder.
214214

215-
During development, the content root defaults to the project's root directory. This directory is also the base path for both the app's content files and the [Web root](#web-root). Specify a different content root by setting its path when [building the host](#host). For more information, see [Content root](xref:fundamentals/host/generic-host#contentroot).
215+
During development, the content root defaults to the project's root directory. This directory is also the base path for both the app's content files and the [web root](#web-root). Specify a different content root by setting its path when [building the host](#host). For more information, see [Content root](xref:fundamentals/host/generic-host#contentroot).
216216

217217
## Web root
218218

@@ -222,9 +222,9 @@ The web root is the base path for public, static resource files, such as:
222222
* JavaScript (`.js`)
223223
* Images (`.png`, `.jpg`)
224224

225-
By default, static files are served only from the web root directory and its sub-directories. The web root path defaults to *{content root}/wwwroot*. Specify a different web root by setting its path when [building the host](#host). For more information, see [Web root](xref:fundamentals/host/generic-host#webroot).
225+
By default, static files are served only from the web root directory and its sub-directories. The web root path defaults to `{CONTENT ROOT}/wwwroot`, where the `{CONTENT ROOT}` placeholder is the content root. Specify a different web root by setting its path when [building the host](#host). For more information, see [Web root](xref:fundamentals/host/generic-host#webroot).
226226

227-
Prevent publishing files in *wwwroot* with the [\<Content> project item](/visualstudio/msbuild/common-msbuild-project-items#content) in the project file. The following example prevents publishing content in *wwwroot/local* and its sub-directories:
227+
Prevent publishing files in `wwwroot` with the [`<Content>` project item](/visualstudio/msbuild/common-msbuild-project-items#content) in the project file. The following example prevents publishing content in `wwwroot/local` and its sub-directories:
228228

229229
```xml
230230
<ItemGroup>

aspnetcore/fundamentals/map-static-files.md

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
---
22
title: Map static files in ASP.NET Core
3-
author: rick-anderson
3+
author: guardrex
44
description: Learn how to serve and secure mapped static files and configure static file hosting middleware behaviors in an ASP.NET Core web app.
55
monikerRange: '>= aspnetcore-9.0'
6-
ms.author: riande
6+
ms.author: wpickett
77
ms.custom: mvc
8-
ms.date: 06/09/2025
8+
ms.date: 07/23/2025
99
uid: fundamentals/map-static-files
1010
---
1111
# Map static files in ASP.NET Core
@@ -16,40 +16,21 @@ uid: fundamentals/map-static-files
1616
1717
-->
1818

19-
By [Rick Anderson](https://twitter.com/RickAndMSFT)
20-
2119
Static files, such as HTML, CSS, images, and JavaScript, are assets an ASP.NET Core app serves directly to clients by default.
2220

2321
For Blazor static files guidance, which adds to or supersedes the guidance in this article, see <xref:blazor/fundamentals/static-files>.
2422

25-
## Serve static files
26-
27-
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).
28-
29-
The <xref:Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder%2A> method sets the content root to the current directory:
30-
31-
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet&highlight=1,15)]
32-
33-
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:
34-
35-
* `wwwroot`
36-
* `css`
37-
* `js`
38-
* `lib`
39-
40-
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`
41-
4223
### Map Static Assets routing endpoint conventions (`MapStaticAssets`)
4324

4425
Creating performant web apps requires optimizing asset delivery to the browser. Possible optimizations with <xref:Microsoft.AspNetCore.Builder.StaticAssetsEndpointRouteBuilderExtensions.MapStaticAssets%2A> include:
4526

46-
* 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) and [Last-Modified](https://developer.mozilla.org/docs/Web/HTTP/Headers/Last-Modified) headers.
47-
* 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.
48-
* Set up proper [caching headers](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control).
27+
* 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) and [Last-Modified](https://developer.mozilla.org/docs/Web/HTTP/Headers/Last-Modified) headers.
28+
* 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.
29+
* Set appropriate [caching headers](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control) on the response.
4930
* Use [Caching Middleware](xref:performance/caching/middleware).
5031
* Serve [compressed](/aspnet/core/performance/response-compression) versions of the assets when possible. This optimization doesn't include minification.
5132
* Use a [CDN](/microsoft-365/enterprise/content-delivery-networks?view=o365-worldwide&preserve-view=true) to serve the assets closer to the user.
52-
* [Fingerprinting assets](https://en.wikipedia.org/wiki/Fingerprint_(computing)) to prevent reusing old versions of files.
33+
* [Fingerprinting assets](https://wikipedia.org/wiki/Fingerprint_(computing)) to prevent reusing old versions of files.
5334

5435
`MapStaticAssets`:
5536

@@ -78,13 +59,6 @@ Map Static Assets doesn't provide features for minification or other file transf
7859

7960
The following features are supported with `UseStaticFiles` but not with `MapStaticAssets`:
8061

81-
* [Serving files from disk or embedded resources, or other locations](xref:fundamentals/static-files#serve-files-from-multiple-locations)
82-
* [Serve files outside of web root](xref:fundamentals/static-files#serve-files-outside-of-web-root)
83-
* [Set HTTP response headers](xref:fundamentals/static-files#set-http-response-headers)
84-
* [Directory browsing](xref:fundamentals/static-files#directory-browsing)
85-
* [Serve default documents](xref:fundamentals/static-files#serve-default-documents)
86-
* [`FileExtensionContentTypeProvider`](xref:fundamentals/static-files#fileextensioncontenttypeprovider)
87-
* [Serve files from multiple locations](xref:fundamentals/static-files#serve-files-from-multiple-locations)
8862
* [Serving files from disk or embedded resources, or other locations](xref:fundamentals/static-files#serve-files-from-multiple-locations)
8963
* [Serve files outside of web root](xref:fundamentals/static-files#serve-files-outside-of-web-root)
9064
* [Set HTTP response headers](xref:fundamentals/static-files#set-http-response-headers)
@@ -95,21 +69,37 @@ The following features are supported with `UseStaticFiles` but not with `MapStat
9569

9670
### Serve files in web root
9771

98-
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:
72+
In the app's `Program` file, <xref:Microsoft.AspNetCore.Builder.WebApplication.CreateBuilder%2A?displayProperty=nameWithType> sets the [content root](xref:fundamentals/index#content-root) to the current directory. Call <xref:Microsoft.AspNetCore.Builder.StaticAssetsEndpointRouteBuilderExtensions.MapStaticAssets%2A> method to enable serving static files. The parameterless overload results in serving the files from the app's [web root](xref:fundamentals/index#web-root). The default web root directory is `{CONTENT ROOT}/wwwroot`, where the `{CONTENT ROOT}` placeholder is the content root.
73+
74+
```csharp
75+
var builder = WebApplication.CreateBuilder(args);
76+
77+
...
78+
79+
app.MapStaticAssets();
80+
```
81+
82+
You can change the web root with the <xref:Microsoft.AspNetCore.Hosting.HostingAbstractionsWebHostBuilderExtensions.UseWebRoot%2A> method. For more information, see the [Content root](xref:fundamentals/index#content-root) and [Web root](xref:fundamentals/index#web-root) sections of the *ASP.NET Core fundamentals overview* article.
9983

100-
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet&highlight=15)]
84+
Static files are accessible via a path relative to the web root. For example, the Blazor Web App project template contains the `lib` folder within the `wwwroot` folder, which contains Bootstrap static assets.
10185

102-
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`:
86+
If an app placed its images in an `images` folder in `wwwroot`, the following markup references `wwwroot/images/favicon.png`:
10387

10488
```html
105-
<img src="~/images/MyImage.jpg" class="img" alt="My image" />
89+
<link rel="icon" type="image/png" href="images/favicon.png" />
90+
```
91+
92+
In Razor Pages and MVC apps (but not Blazor apps), the tilde character `~` points to the web root. In the following example, `~/images/icon.jpg` loads the icon image (`icon.jpg`) from the app's `wwwroot/images` folder:
93+
94+
```cshtml
95+
<img src="~/images/icon.jpg" alt="Icon image" />
10696
```
10797

108-
In the preceding markup, the tilde character `~` points to the [web root](xref:fundamentals/index#web-root).
98+
The URL format for the preceding example is `https://{HOST}/images/{FILE NAME}`. The `{HOST}` placeholder is the host, and the `{FILE NAME}` placeholder is the file name. For the preceding example running at the app's localhost address on port 5001, the absolute URL is `https://localhost:5001/images/icon.jpg`.
10999

110100
### Serve files outside of web root
111101

112-
Consider a directory hierarchy in which the static files to be served reside outside of the [web root](xref:fundamentals/index#web-root):
102+
Consider the following directory hierarchy with static files residing outside of the app's [web root](xref:fundamentals/index#web-root) in a folder named `MyStaticFiles`:
113103

114104
* `wwwroot`
115105
* `css`
@@ -121,19 +111,19 @@ Consider a directory hierarchy in which the static files to be served reside out
121111

122112
A request can access the `red-rose.jpg` file by configuring the Static File Middleware as follows:
123113

124-
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_rr&highlight=1,18-23)]
114+
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_rr&highlight=1,18-24)]
125115

126-
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.
116+
In the preceding code, the `MyStaticFiles` directory hierarchy is exposed publicly via the `StaticFiles` URL segment. A request to `https://{HOST}/StaticFiles/images/red-rose.jpg`, where the `{HOST}` placeholder is the host, serves the `red-rose.jpg` file.
127117

128118
The following markup references `MyStaticFiles/images/red-rose.jpg`:
129-
<!-- zz test via /Home2/MyStaticFilesRR -->
119+
130120
[!code-html[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Views/Home2/MyStaticFilesRR.cshtml?range=1)]
131121

132122
To serve files from multiple locations, see [Serve files from multiple locations](xref:fundamentals/static-files#serve-files-from-multiple-locations).
133123

134124
### Set HTTP response headers
135125

136-
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:
126+
A <xref:Microsoft.AspNetCore.Builder.StaticFileOptions> object can be used to set HTTP response headers. In addition to configuring the middleware to serve static files 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:
137127

138128
[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_rh&highlight=16-24)]
139129

@@ -143,9 +133,9 @@ The preceding code makes static files publicly available in the local cache for
143133

144134
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:
145135

146-
* No authorization checks are performed on the static files.
147-
* Static files served by the Static File Middleware, such as those under `wwwroot`, are publicly accessible.
148-
136+
* No authorization checks are performed on the static files.
137+
* Static files served by the Static File Middleware, such as those under `wwwroot`, are publicly accessible.
138+
149139
To serve static files based on authorization, see [Static file authorization](xref:fundamentals/static-files#static-file-authorization).
150140

151141
## Serve files from multiple locations
@@ -161,7 +151,7 @@ Consider the following Razor page which displays the `/MyStaticFiles/image3.png`
161151
Using the preceding code:
162152

163153
* The `/MyStaticFiles/image3.png` file is displayed.
164-
* 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.
154+
* [Image Tag Helpers](xref:mvc/views/tag-helpers/builtin-th/image-tag-helper) (<xref:Microsoft.AspNetCore.Mvc.TagHelpers.ImageTagHelper.AppendVersion>) aren't applied because Tag Helpers depend on <xref:Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootFileProvider>. `WebRootFileProvider` hasn't been updated to include the `MyStaticFiles` folder.
165155

166156
The following code updates the `WebRootFileProvider`, which enables the Image Tag Helper to provide a version:
167157

@@ -170,7 +160,7 @@ The following code updates the `WebRootFileProvider`, which enables the Image Ta
170160
> [!NOTE]
171161
> 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>.
172162
173-
## Serve files outside wwwroot by updating IWebHostEnvironment.WebRootPath
163+
## Serve files outside wwwroot by updating `IWebHostEnvironment.WebRootPath`
174164

175165
When <xref:Microsoft.AspNetCore.Hosting.IWebHostEnvironment.WebRootPath%2A?displayProperty=nameWithType> is set to a folder other than `wwwroot`:
176166

@@ -186,8 +176,8 @@ Consider a web app created with the empty web template:
186176

187177
In the preceding code, requests to `/`:
188178

189-
* In the development environment return `wwwroot/Index.html`
190-
* In any environment other than development return `wwwroot-custom/Index.html`
179+
* In the development environment, return `wwwroot/Index.html`.
180+
* In any environment other than development, return `wwwroot-custom/Index.html`.
191181

192182
To ensure assets from `wwwroot-custom` are returned, use one of the following approaches:
193183

@@ -202,14 +192,15 @@ To ensure assets from `wwwroot-custom` are returned, use one of the following ap
202192
</ItemGroup>
203193
```
204194

205-
The following code updates `IWebHostEnvironment.WebRootPath` to a non development value, guaranteeing duplicate content is returned from `wwwroot-custom` rather than `wwwroot`:
195+
The following code updates `IWebHostEnvironment.WebRootPath` to a non-Development value (Staging), guaranteeing duplicate content is returned from `wwwroot-custom` rather than `wwwroot`:
206196

207197
[!code-csharp[](~/fundamentals/static-files/samples/9.x/WebRoot/Program.cs?name=snippet2&highlight=5)]
208198

199+
When developing a server-side Blazor app and testing locally, see <xref:blazor/fundamentals/static-files#static-files-in-non-development-environments>.
200+
209201
## Additional resources
210202

211203
* [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))
212-
* [Middleware](xref:fundamentals/middleware/index)
213-
* [Introduction to ASP.NET Core](xref:index)
204+
* <xref:fundamentals/middleware/index>
214205
* <xref:blazor/file-uploads>
215206
* <xref:blazor/file-downloads>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
@page
1+
@page
22
@model IndexModel
33
@{
44
ViewData["Title"] = "RP Home page";
55
}
66

77
<div class="text-center">
88
<h1 class="display-4">RP pages Welcome</h1>
9-
<p>Learn about <a href="~/MyImages">Directy browsing</a>.</p>
9+
<p>Learn about <a href="~/MyImages">Directory browsing</a>.</p>
1010
</div>

aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Pages/Privacy.cshtml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77

88
<p>RP: Use this page to detail your site's privacy policy.</p>
99

10-
<p>The following inmage doesn't display with app.UseStaticFiles(new StaticFileOptions </p>
10+
<p>The following image doesn't display with <code>app.UseStaticFiles(new StaticFileOptions ...)</code>.</p>
11+
1112
<img src="~/images/MyImage.jpg" class="img" alt="My image" asp-append-version="true" />
13+
1214
<p> The following image requires:</p>
15+
1316
<pre><code>
1417
app.UseStaticFiles(new StaticFileOptions //
1518
{

aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Pages/Shared/_Layout.cshtml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!DOCTYPE html>
1+
<!DOCTYPE html>
22
<html lang="en">
33
<head>
44
<meta charset="utf-8" />
@@ -25,7 +25,7 @@
2525
<li class="nav-item">
2626
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">RP Privacy</a>
2727
</li>
28-
<li class="nav-item">
28+
<li class="nav-item">
2929
<a class="nav-link text-dark" asp-area="" asp-controller="Home2" asp-action="Index">MVC Home</a>
3030
</li>
3131
<li class="nav-item">
@@ -54,4 +54,4 @@
5454

5555
@await RenderSectionAsync("Scripts", required: false)
5656
</body>
57-
</html>
57+
</html>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@page
22

3-
<p> Test /MyStaticFiles/image3.png</p>
3+
<p>Test /MyStaticFiles/image3.png</p>
44

55
<img src="~/image3.png" class="img" asp-append-version="true" alt="Test">

0 commit comments

Comments
 (0)