From 1ac3e7edca028c3be05bc7db7f8c489d30a18e87 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:27:34 -1000 Subject: [PATCH 01/15] Move to GitStaticAssets --- .../samples/9.x/StaticFilesSample/Program.cs | 26 +++++++++---------- .../StaticFilesSample.csproj | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs index bb4e9fac93b7..6dfdf93f6d84 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs @@ -16,7 +16,7 @@ } app.UseHttpsRedirection(); -app.UseStaticFiles(); +app.MapStaticAssets(); app.UseAuthorization(); @@ -44,12 +44,12 @@ app.UseHttpsRedirection(); -app.UseStaticFiles(new StaticFileOptions -{ - FileProvider = new PhysicalFileProvider( - Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), - RequestPath = "/StaticFiles" -}); + app.UseStaticFiles(new StaticFileOptions + { + FileProvider = new PhysicalFileProvider( + Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), + RequestPath = "/StaticFiles" + }); app.UseAuthorization(); @@ -114,7 +114,7 @@ app.UseHttpsRedirection(); -app.UseStaticFiles(); +app.MapStaticAssets(); var fileProvider = new PhysicalFileProvider(Path.Combine(builder.Environment.WebRootPath, "images")); var requestPath = "/MyImages"; @@ -158,7 +158,7 @@ app.UseDefaultFiles(); -app.UseStaticFiles(); +app.MapStaticAssets(); app.UseAuthorization(); app.MapDefaultControllerRoute(); @@ -188,7 +188,7 @@ options.DefaultFileNames.Add("mydefault.html"); app.UseDefaultFiles(options); -app.UseStaticFiles(); +app.MapStaticAssets(); app.UseAuthorization(); @@ -274,7 +274,7 @@ app.UseHttpsRedirection(); -app.UseStaticFiles(); +app.MapStaticAssets(); app.UseFileServer(new FileServerOptions { @@ -383,7 +383,7 @@ app.UseHttpsRedirection(); // -app.UseStaticFiles(); // Serve files from wwwroot +app.MapStaticAssets(); // Serve files from wwwroot with MapStaticAssets app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( @@ -426,7 +426,7 @@ // Update the default provider. app.Environment.WebRootFileProvider = compositeProvider; -app.UseStaticFiles(); +app.MapStaticAssets(); // diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/StaticFilesSample.csproj b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/StaticFilesSample.csproj index 9e8317646abe..4e404415b4a3 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/StaticFilesSample.csproj +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/StaticFilesSample.csproj @@ -1,7 +1,7 @@ - net6.0 + net9.0 enable enable From 5bfd4c95b224af130850188d4a6fe0b6a63f6eec Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:29:20 -1000 Subject: [PATCH 02/15] Move to GitStaticAssets --- .../samples/9.x/StaticFilesSample/Program.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs index 6dfdf93f6d84..55d299ad53b4 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs @@ -44,12 +44,12 @@ app.UseHttpsRedirection(); - app.UseStaticFiles(new StaticFileOptions - { - FileProvider = new PhysicalFileProvider( - Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), - RequestPath = "/StaticFiles" - }); +app.UseStaticFiles(new StaticFileOptions // +{ + FileProvider = new PhysicalFileProvider( + Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), + RequestPath = "/StaticFiles" +}); app.UseAuthorization(); From dc32a100c5be97357f8c8ffa07da7952340efe62 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 10 Jul 2024 19:32:30 -1000 Subject: [PATCH 03/15] Move to GitStaticAssets --- aspnetcore/fundamentals/static-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 6d0520649819..e0cc62519e2c 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -5,7 +5,7 @@ description: Learn how to serve and secure static files and configure static fil monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc -ms.date: 7/4/2024 +ms.date: 7/10/2024 uid: fundamentals/static-files --- # Static files in ASP.NET Core From 463737f6e0da93dc4d964c1b54387978dde03bc5 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:24:02 -1000 Subject: [PATCH 04/15] Move to GitStaticAssets --- .../StaticFilesSample/Pages/Privacy.cshtml | 13 +++ .../samples/9.x/StaticFilesSample/Program.cs | 102 ++++++++++++------ .../samples/9.x/WebRoot/Program.cs | 6 +- .../samples/9.x/WebRoot/WebRoot.csproj | 2 +- 4 files changed, 86 insertions(+), 37 deletions(-) diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Pages/Privacy.cshtml b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Pages/Privacy.cshtml index 0baf7b951997..c9aa449da6a8 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Pages/Privacy.cshtml +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Pages/Privacy.cshtml @@ -7,4 +7,17 @@

RP: Use this page to detail your site's privacy policy.

+

The following inmage doesn't display with app.UseStaticFiles(new StaticFileOptions

My image +

The following image requires:

+

+app.UseStaticFiles(new StaticFileOptions //
+{
+  FileProvider = new PhysicalFileProvider(
+      Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")),
+  RequestPath = "/StaticFiles"
+});
+
+ +A red rose diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs index 55d299ad53b4..32acdaceee9d 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs @@ -1,4 +1,5 @@ -#define MULT2 // DEFAULT RR RH DB DF DF2 UFS UFS2 TREE FECTP NS MUL MULT2 +#define RR // DEFAULT RR RH DB DF DF2 UFS UFS2 TREE FECTP NS MUL MULT2 +// Test1 #if NEVER #elif DEFAULT // @@ -20,8 +21,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -44,17 +45,18 @@ app.UseHttpsRedirection(); -app.UseStaticFiles(new StaticFileOptions // -{ - FileProvider = new PhysicalFileProvider( - Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), - RequestPath = "/StaticFiles" -}); +//app.UseStaticFiles(); // required for https://localhost:/images/MyImage.jpg + app.UseStaticFiles(new StaticFileOptions + { + FileProvider = new PhysicalFileProvider( + Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), + RequestPath = "/StaticFiles" + }); app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -87,8 +89,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -134,8 +136,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -161,8 +163,8 @@ app.MapStaticAssets(); app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -192,8 +194,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -218,8 +220,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -248,8 +250,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -286,8 +288,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -329,8 +331,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -359,8 +361,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); // @@ -393,8 +395,8 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); #elif MULT2 @@ -432,8 +434,42 @@ app.UseAuthorization(); -app.MapDefaultControllerRoute(); -app.MapRazorPages(); +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); app.Run(); +#elif Test1 +using Microsoft.Extensions.FileProviders; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddRazorPages(); +builder.Services.AddControllersWithViews(); + +var app = builder.Build(); + +if (!app.Environment.IsDevelopment()) +{ + app.UseExceptionHandler("/Error"); + app.UseHsts(); +} + +app.UseHttpsRedirection(); + +app.UseStaticFiles(); // required for https://localhost:50921/images/MyImage.jpg + +app.UseStaticFiles(new StaticFileOptions +{ + FileProvider = new PhysicalFileProvider( + Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), + RequestPath = "/StaticFiles" +}); + +app.UseAuthorization(); + +app.MapDefaultControllerRoute().WithStaticAssets(); +app.MapRazorPages().WithStaticAssets(); + +app.Run(); +// #endif diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/Program.cs index 59031d7ec791..32471a5c09cf 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/Program.cs @@ -1,4 +1,4 @@ -#define FIRST // FIRST +#define SECOND // FIRST SECOND #if NEVER #elif FIRST // @@ -12,7 +12,7 @@ var app = builder.Build(); app.UseDefaultFiles(); -app.UseStaticFiles(); +app.MapStaticAssets(); app.Run(); // @@ -35,7 +35,7 @@ app.Environment.IsDevelopment().ToString()); app.UseDefaultFiles(); -app.UseStaticFiles(); +app.MapStaticAssets(); app.Run(); // diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/WebRoot.csproj b/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/WebRoot.csproj index cae4bd2ba86e..99769afd6147 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/WebRoot.csproj +++ b/aspnetcore/fundamentals/static-files/samples/9.x/WebRoot/WebRoot.csproj @@ -1,7 +1,7 @@ - net6.0 + net9.0 enable enable From 23b20dd40561bfb390465a575602eb3bfc3df127 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:27:19 -1000 Subject: [PATCH 05/15] Move to GitStaticAssets --- .../samples/9.x/StaticFilesSample/Program.cs | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs index 32acdaceee9d..07cd5e84c3e8 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs @@ -77,15 +77,15 @@ app.UseHttpsRedirection(); -var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString(); -app.UseStaticFiles(new StaticFileOptions -{ - OnPrepareResponse = ctx => - { - ctx.Context.Response.Headers.Append( - "Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}"); - } -}); + var cacheMaxAgeOneWeek = (60 * 60 * 24 * 7).ToString(); + app.UseStaticFiles(new StaticFileOptions + { + OnPrepareResponse = ctx => + { + ctx.Context.Response.Headers.Append( + "Cache-Control", $"public, max-age={cacheMaxAgeOneWeek}"); + } + }); app.UseAuthorization(); @@ -353,11 +353,11 @@ app.UseHttpsRedirection(); -app.UseStaticFiles(new StaticFileOptions -{ - ServeUnknownFileTypes = true, - DefaultContentType = "image/png" -}); + app.UseStaticFiles(new StaticFileOptions + { + ServeUnknownFileTypes = true, + DefaultContentType = "image/png" + }); app.UseAuthorization(); @@ -385,12 +385,12 @@ app.UseHttpsRedirection(); // -app.MapStaticAssets(); // Serve files from wwwroot with MapStaticAssets -app.UseStaticFiles(new StaticFileOptions -{ - FileProvider = new PhysicalFileProvider( - Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")) -}); + app.UseStaticFiles(); + app.UseStaticFiles(new StaticFileOptions + { + FileProvider = new PhysicalFileProvider( + Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")) + }); // app.UseAuthorization(); From e53fa72acb887b8868617e56770f9d671ba3004b Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:33:30 -1000 Subject: [PATCH 06/15] Move to GitStaticAssets --- .../static-files/samples/9.x/StaticFilesSample/Program.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs index 07cd5e84c3e8..f40150e9fd3a 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs @@ -45,8 +45,8 @@ app.UseHttpsRedirection(); -//app.UseStaticFiles(); // required for https://localhost:/images/MyImage.jpg - app.UseStaticFiles(new StaticFileOptions +app.UseStaticFiles(); //Serve files from wwwroot +app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( Path.Combine(builder.Environment.ContentRootPath, "MyStaticFiles")), @@ -456,7 +456,7 @@ app.UseHttpsRedirection(); -app.UseStaticFiles(); // required for https://localhost:50921/images/MyImage.jpg +app.UseStaticFiles(); // Serve files from wwwroot app.UseStaticFiles(new StaticFileOptions { From 435107230fbe22df24503ee03bf3853a3dcb8b6b Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Fri, 12 Jul 2024 18:57:24 -1000 Subject: [PATCH 07/15] Move to GitStaticAssets --- aspnetcore/fundamentals/static-files.md | 2 +- .../release-notes/aspnetcore-9/includes/web_asset_delivery.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index e0cc62519e2c..98dd7c9ca5d7 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -24,7 +24,7 @@ Static files are stored within the project's [web root](xref:fundamentals/index# The method sets the content root to the current directory: -[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet&highlight=1)] +[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet&highlight=1,15)] 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: diff --git a/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md b/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md index dff1b1936961..d476db683611 100644 --- a/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md +++ b/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md @@ -16,7 +16,7 @@ Creating performant web apps requires optimizing asset delivery to the browser. * Use a [CDN](/microsoft-365/enterprise/content-delivery-networks?view=o365-worldwide&preserve-view=true) to serve the assets closer to the user. * Minimize the size of assets served to the browser. This optimization doesn't include minification. -[`MapStaticAssets`](https://source.dot.net/#Microsoft.AspNetCore.StaticAssets/StaticAssetsEndpointRouteBuilderExtensions.cs,18) is a new middleware that helps optimize the delivery of static assets in an app. It's designed to work with all UI frameworks, including Blazor, Razor Pages, and MVC. It's typically a drop-in replacement for [UseStaticFiles](/dotnet/api/microsoft.aspnetcore.builder.staticfileextensions.usestaticfiles): +[`MapStaticAssets`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.builder.staticassetsendpointroutebuilderextensions.mapstaticassets) is a new middleware that helps optimize the delivery of static assets in an app. It's designed to work with all UI frameworks, including Blazor, Razor Pages, and MVC. It's typically a drop-in replacement for [UseStaticFiles](/dotnet/api/microsoft.aspnetcore.builder.staticfileextensions.usestaticfiles): ```diff var builder = WebApplication.CreateBuilder(args); From a14c2806c7f435e65ab022d373a91907b3277dad Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Fri, 12 Jul 2024 19:04:30 -1000 Subject: [PATCH 08/15] Move to GitStaticAssets --- aspnetcore/fundamentals/static-files.md | 14 +++++++++++++- .../aspnetcore-9/includes/web_asset_delivery.md | 4 ++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 98dd7c9ca5d7..4e67dff41cca 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -37,7 +37,19 @@ Consider creating the *wwwroot/images* folder and adding the `wwwroot/images/MyI ### MapStaticAssets -`MapStaticAssets` is a middleware that helps optimize the delivery of static assets in an app. For more information, see [Optimizing static web asset delivery +Creating performant web apps requires optimizing asset delivery to the browser. Possible optimizations include: + +* 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. +* 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. +* Set up proper [caching headers](https://developer.mozilla.org/docs/Web/HTTP/Headers/Cache-Control). +* Use [caching middleware](xref:performance/caching/middleware). +* Serve [compressed](/aspnet/core/performance/response-compression) versions of the assets when possible. +* Use a [CDN](/microsoft-365/enterprise/content-delivery-networks?view=o365-worldwide&preserve-view=true) to serve the assets closer to the user. +* Minimize the size of assets served to the browser. This optimization doesn't include minification. + +[`MapStaticAssets`](/dotnet/api/microsoft.aspnetcore.builder.staticassetsendpointroutebuilderextensions.mapstaticassets) is a middleware that helps optimize the delivery of static assets in an app. It's designed to work with all UI frameworks, including Blazor, Razor Pages, and MVC. + +[`UseStaticFiles`](/dotnet/api/microsoft.aspnetcore.builder.staticfileextensions.usestaticfiles) also serves static files, but it doesn't provide the same level of optimization as `MapStaticAssets`. For a comparison of `UseStaticFiles` and `MapStaticAssets`, see [Optimizing static web asset delivery ](xref:aspnetcore-9#optimizing-static-web-asset-delivery). ### Serve files in web root diff --git a/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md b/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md index d476db683611..69636d34ed7d 100644 --- a/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md +++ b/aspnetcore/release-notes/aspnetcore-9/includes/web_asset_delivery.md @@ -16,7 +16,7 @@ Creating performant web apps requires optimizing asset delivery to the browser. * Use a [CDN](/microsoft-365/enterprise/content-delivery-networks?view=o365-worldwide&preserve-view=true) to serve the assets closer to the user. * Minimize the size of assets served to the browser. This optimization doesn't include minification. -[`MapStaticAssets`](https://learn.microsoft.com/dotnet/api/microsoft.aspnetcore.builder.staticassetsendpointroutebuilderextensions.mapstaticassets) is a new middleware that helps optimize the delivery of static assets in an app. It's designed to work with all UI frameworks, including Blazor, Razor Pages, and MVC. It's typically a drop-in replacement for [UseStaticFiles](/dotnet/api/microsoft.aspnetcore.builder.staticfileextensions.usestaticfiles): +[`MapStaticAssets`](/dotnet/api/microsoft.aspnetcore.builder.staticassetsendpointroutebuilderextensions.mapstaticassets) is a new middleware that helps optimize the delivery of static assets in an app. It's designed to work with all UI frameworks, including Blazor, Razor Pages, and MVC. It's typically a drop-in replacement for [UseStaticFiles](/dotnet/api/microsoft.aspnetcore.builder.staticfileextensions.usestaticfiles): ```diff var builder = WebApplication.CreateBuilder(args); @@ -46,7 +46,7 @@ app.Run(); `MapStaticAssets` operates by combining build and publish-time processes to collect information about all the static resources in an app. This information is then utilized by the runtime library to efficiently serve these files to the browser. -`MapStaticAssets` can replace `UseStaticFiles` in most situations, however, it's optimized for serving the assets that the app has knowledge of at build and publish time. If the app serves assets from other locations, such as disk or embedded resources, `UseStaticFiles` should be used. +`MapStaticAssets` can replace [`UseStaticFiles`](/dotnet/api/microsoft.aspnetcore.builder.staticfileextensions.usestaticfiles) in most situations, however, it's optimized for serving the assets that the app has knowledge of at build and publish time. If the app serves assets from other locations, such as disk or embedded resources, `UseStaticFiles` should be used. `MapStaticAssets` provides the following benefits not found with `UseStaticFiles`: From dfd6cf033c98dd8e9663de2cb2c648634142fdd6 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:53:43 -1000 Subject: [PATCH 09/15] Move to GitStaticAssets --- .../static-files/samples/9.x/StaticFilesSample/Program.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs index f40150e9fd3a..5d0a7306205e 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs @@ -1,4 +1,4 @@ -#define RR // DEFAULT RR RH DB DF DF2 UFS UFS2 TREE FECTP NS MUL MULT2 +#define DEFAULT // DEFAULT RR RH DB DF DF2 UFS UFS2 TREE FECTP NS MUL MULT2 // Test1 #if NEVER #elif DEFAULT @@ -438,7 +438,7 @@ app.MapRazorPages().WithStaticAssets(); app.Run(); -#elif Test1 +#elif Test1 // no snippet to import, just for testing using Microsoft.Extensions.FileProviders; var builder = WebApplication.CreateBuilder(args); @@ -471,5 +471,4 @@ app.MapRazorPages().WithStaticAssets(); app.Run(); -// #endif From aa203395538b1105563907e69de91a13c84ecfcb Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 24 Jul 2024 13:59:30 -1000 Subject: [PATCH 10/15] work --- aspnetcore/fundamentals/static-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 4e67dff41cca..91a3ed9d868a 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -5,7 +5,7 @@ description: Learn how to serve and secure static files and configure static fil monikerRange: '>= aspnetcore-3.1' ms.author: riande ms.custom: mvc -ms.date: 7/10/2024 +ms.date: 7/25/2024 uid: fundamentals/static-files --- # Static files in ASP.NET Core From 7b5f02bd026198e1cfd7ea586ab9959ac8b2ae63 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:27:21 -1000 Subject: [PATCH 11/15] work --- aspnetcore/fundamentals/static-files.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 91a3ed9d868a..78baa6ce8657 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -33,7 +33,7 @@ Static files are accessible via a path relative to the [web root](xref:fundament * `js` * `lib` -Consider creating the *wwwroot/images* folder and adding the `wwwroot/images/MyImage.jpg` file. The URI format to access a file in the `images` folder is `https:///images/`. For example, `https://localhost:5001/images/MyImage.jpg` +Consider an app with the `wwwroot/images/MyImage.jpg` file. The URI format to access a file in the `images` folder is `https:///images/`. For example, `https://localhost:5001/images/MyImage.jpg` ### MapStaticAssets @@ -54,7 +54,7 @@ Creating performant web apps requires optimizing asset delivery to the browser. ### Serve files in web root -The default web app templates call the method in `Program.cs`, which enables static files to be served: +The default web app templates call the [`MapStaticAssets`](/dotnet/api/microsoft.aspnetcore.builder.staticassetsendpointroutebuilderextensions.mapstaticassets) method in `Program.cs`, which enables static files to be served: [!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet&highlight=15)] @@ -96,11 +96,11 @@ A object can be used to se [!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_rh&highlight=16-24)] -The preceding code makes static files publicly available in the local cache for one week (604800 seconds). +The preceding code makes static files publicly available in the local cache for one week. ## Static file authorization -The ASP.NET Core templates call before calling . Most apps follow this pattern. When the Static File Middleware is called before the authorization middleware: +The ASP.NET Core templates call [`MapStaticAssets`](/dotnet/api/microsoft.aspnetcore.builder.staticassetsendpointroutebuilderextensions.mapstaticassets) before calling . Most apps follow this pattern. When the Static File Middleware is called before the authorization middleware: * No authorization checks are performed on the static files. * Static files served by the Static File Middleware, such as those under `wwwroot`, are publicly accessible. @@ -111,7 +111,7 @@ To serve static files based on authorization: * Call `UseStaticFiles`, specifying a path, after calling `UseAuthorization`. * Set the [fallback authorization policy](xref:Microsoft.AspNetCore.Authorization.AuthorizationOptions.FallbackPolicy). -[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFileAuth/Program.cs?name=snippet_auth&highlight=18-23,38,45-50)] +[!code-csharp[](~/fundamentals/static-files/samples/8.x/StaticFileAuth/Program.cs?name=snippet_auth&highlight=18-23,38,45-50)] In the preceding code, the fallback authorization policy requires ***all*** users to be authenticated. Endpoints such as controllers, Razor Pages, etc that specify their own authorization requirements don't use the fallback authorization policy. For example, Razor Pages, controllers, or action methods with `[AllowAnonymous]` or `[Authorize(PolicyName="MyPolicy")]` use the applied authorization attribute rather than the fallback authorization policy. From a3660e5d295cf6decec97bc25b26a77ae200c5a5 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:33:09 -1000 Subject: [PATCH 12/15] work --- aspnetcore/fundamentals/static-files.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 78baa6ce8657..1def958831cd 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -117,7 +117,7 @@ To serve static files based on authorization: adds to the current instance, which enforces that the current user is authenticated. - Static assets under `wwwroot` are publicly accessible because the default Static File Middleware (`app.UseStaticFiles();`) is called before `UseAuthentication`. Static assets in the ***MyStaticFiles*** folder require authentication. The [sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/static-files/samples/9.x) demonstrates this. + Static assets under `wwwroot` are publicly accessible because the default Static File Middleware (`app.UseStaticFiles();`) is called before `UseAuthentication`. Static assets in the ***MyStaticFiles*** folder require authentication. The [sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/static-files/samples/8.x) demonstrates this. An alternative approach to serve files based on authorization is to: From 6078a809f1fc0cca8a946872b4e9f6f790116aa4 Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:39:55 -1000 Subject: [PATCH 13/15] work --- aspnetcore/fundamentals/static-files.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 1def958831cd..554f458a17ab 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -111,7 +111,8 @@ To serve static files based on authorization: * Call `UseStaticFiles`, specifying a path, after calling `UseAuthorization`. * Set the [fallback authorization policy](xref:Microsoft.AspNetCore.Authorization.AuthorizationOptions.FallbackPolicy). -[!code-csharp[](~/fundamentals/static-files/samples/8.x/StaticFileAuth/Program.cs?name=snippet_auth&highlight=18-23,38,45-50)] + +[!code-csharp[](~/fundamentals/static-files/samples/6.x/StaticFileAuth/Program.cs?name=snippet_auth&highlight=18-23,38,45-50)] In the preceding code, the fallback authorization policy requires ***all*** users to be authenticated. Endpoints such as controllers, Razor Pages, etc that specify their own authorization requirements don't use the fallback authorization policy. For example, Razor Pages, controllers, or action methods with `[AllowAnonymous]` or `[Authorize(PolicyName="MyPolicy")]` use the applied authorization attribute rather than the fallback authorization policy. From 1be8482bc0d39a788e4a808b07cc7b98a97065be Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:04:32 -1000 Subject: [PATCH 14/15] work --- aspnetcore/fundamentals/static-files.md | 3 +++ .../samples/6.x/StaticFileAuth/Program.cs | 14 +++++++------- .../9.x/StaticFileAuth/StaticFilesAuth.csproj | 6 +++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index 554f458a17ab..be47b23f4c78 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -125,12 +125,15 @@ An alternative approach to serve files based on authorization is to: * Store them outside of `wwwroot` and any directory accessible to the Static File Middleware. * Serve them via an action method to which authorization is applied and return a object: + [!code-csharp[](~/fundamentals/static-files/samples/6.x/StaticFileAuth/Pages/BannerImage.cshtml.cs?name=snippet)] The preceding approach requires a page or endpoint per file. The following code returns files or uploads files for authenticated users: :::code language="csharp" source="~/fundamentals/static-files/samples/9.x/StaticFileAuth/Program.cs" id="snippet_1"::: +IFormFile in the preceding sample uses memory buffer for uploading. For handling large file use streaming. See [Upload large files with streaming](/mvc/models/file-uploads#upload-large-files-with-streaming). + See the [StaticFileAuth](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth) GitHub folder for the complete sample. ## Directory browsing diff --git a/aspnetcore/fundamentals/static-files/samples/6.x/StaticFileAuth/Program.cs b/aspnetcore/fundamentals/static-files/samples/6.x/StaticFileAuth/Program.cs index 6dc1e32d7e42..1ad457d86bba 100644 --- a/aspnetcore/fundamentals/static-files/samples/6.x/StaticFileAuth/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/6.x/StaticFileAuth/Program.cs @@ -1,7 +1,7 @@ #define DEFAULT // DEFAULT AUTH AUTH2 #if NEVER #elif DEFAULT -#region snippet +// using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using StaticFileAuth.Data; @@ -38,9 +38,9 @@ app.MapRazorPages(); app.Run(); -#endregion +// #elif AUTH -#region snippet_auth +// using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -95,9 +95,9 @@ app.MapRazorPages(); app.Run(); -#endregion +// #elif AUTH2 -#region snippet_auth2 +// using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; @@ -135,5 +135,5 @@ app.MapRazorPages(); app.Run(); -#endregion -#endif \ No newline at end of file +// +#endif diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/StaticFilesAuth.csproj b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/StaticFilesAuth.csproj index 2644e9e880c3..240b54d9cdff 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/StaticFilesAuth.csproj +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/StaticFilesAuth.csproj @@ -8,9 +8,9 @@ - - - + + + From 13da20cad21e156d8e3b98534f36b14bedb1813a Mon Sep 17 00:00:00 2001 From: Rick Anderson <3605364+Rick-Anderson@users.noreply.github.com> Date: Wed, 24 Jul 2024 15:51:13 -1000 Subject: [PATCH 15/15] work --- aspnetcore/fundamentals/static-files.md | 18 ++++++++++------ .../samples/9.x/StaticFileAuth/Program.cs | 20 +++++++++++------- .../defaultFiles}/default.html | 6 +++--- .../MyStaticFiles/defaultFiles/image3.png | Bin 0 -> 6304 bytes .../samples/9.x/StaticFilesSample/Program.cs | 10 +++++---- .../wwwroot/def/default.html | 11 ++++++++++ .../wwwroot/{ => def}/index.html | 6 +++--- .../wwwroot/{ => def}/myIndex.html | 6 +++--- .../wwwroot/{ => def}/mydefault.html | 6 +++--- 9 files changed, 52 insertions(+), 31 deletions(-) rename aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/{wwwroot => MyStaticFiles/defaultFiles}/default.html (54%) create mode 100644 aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/MyStaticFiles/defaultFiles/image3.png create mode 100644 aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/default.html rename aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/{ => def}/index.html (54%) rename aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/{ => def}/myIndex.html (54%) rename aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/{ => def}/mydefault.html (54%) diff --git a/aspnetcore/fundamentals/static-files.md b/aspnetcore/fundamentals/static-files.md index be47b23f4c78..925052b03aeb 100644 --- a/aspnetcore/fundamentals/static-files.md +++ b/aspnetcore/fundamentals/static-files.md @@ -170,11 +170,11 @@ With `UseDefaultFiles`, requests to a folder in `wwwroot` search for: * `index.htm` * `index.html` -The first file found from the list is served as though the request included the file's name. The browser URL continues to reflect the URI requested. +The first file found from the list is served as though the request included the file's name. The browser URL continues to reflect the URI requested. For example, in the [sample app](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs), a request to `https://localhost:/def/` serves `default.html` from `wwwroot/def`. The following code changes the default file name to `mydefault.html`: -[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_df2&highlight=16-19)] +[!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_df2&highlight=16-19)] ### UseFileServer for default documents @@ -198,9 +198,11 @@ Consider the following directory hierarchy: * `images` * `js` * `MyStaticFiles` + * `defaultFiles` + * `default.html` + * `image3.png` * `images` * `MyImage.jpg` - * `default.html` The following code enables the serving of static files, the default file, and directory browsing of `MyStaticFiles`: @@ -215,7 +217,9 @@ Using the preceding file hierarchy and code, URLs resolve as follows: | URI | Response | | ------- | ------| | `https:///StaticFiles/images/MyImage.jpg` | `MyStaticFiles/images/MyImage.jpg` | -| `https:///StaticFiles` | `MyStaticFiles/default.html` | +| `https:///StaticFiles` | directory listing | +| `https:///StaticFiles/defaultFiles` | `MyStaticFiles/defaultFiles/default.html` | +| `https:///StaticFiles/defaultFiles/image3.png` | `MyStaticFiles/defaultFiles//image3.png` | If no default-named file exists in the *MyStaticFiles* directory, `https:///StaticFiles` returns the directory listing with clickable links: @@ -225,7 +229,7 @@ If no default-named file exists in the *MyStaticFiles* directory, `https:// class contains a `Mappings` property that serves as a mapping of file extensions to MIME content types. In the following sample, several file extensions are mapped to known MIME types. The *.rtf* extension is replaced, and *.mp4* is removed: +The class contains a [Mappings](/dotnet/api/microsoft.aspnetcore.staticfiles.fileextensioncontenttypeprovider.mappings) property that serves as a mapping of file extensions to MIME content types. In the following sample, several file extensions are mapped to known MIME types. The *.rtf* extension is replaced, and *.mp4* is removed: [!code-csharp[](~/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs?name=snippet_fec&highlight=19-33)] @@ -269,9 +273,9 @@ The following code updates the `WebRootFileProvider`, which enables the Image Ta ### Security considerations for static files > [!WARNING] -> `UseDirectoryBrowser` and `UseStaticFiles` can leak secrets. Disabling directory browsing in production is highly recommended. Carefully review which directories are enabled via `UseStaticFiles` or `UseDirectoryBrowser`. The entire directory and its sub-directories become publicly accessible. Store files suitable for serving to the public in a dedicated directory, such as `/wwwroot`. Separate these files from MVC views, Razor Pages, configuration files, etc. +> `UseDirectoryBrowser` and `UseStaticFiles` can leak secrets. Disabling directory browsing in production is highly recommended. Carefully review which directories are enabled via `UseStaticFiles` or `UseDirectoryBrowser`. The entire directory and its sub-directories become publicly accessible. Store files suitable for serving to the public in a dedicated directory, such as `/wwwroot`. Separate these files from MVC views, Razor Pages, configuration files, etc. -* The URLs for content exposed with `UseDirectoryBrowser` and `UseStaticFiles` are subject to the case sensitivity and character restrictions of the underlying file system. For example, Windows is case insensitive, but macOS and Linux aren't. +* The URLs for content exposed with `UseDirectoryBrowser`, `UseStaticFiles`, and `MapStaticAssets` are subject to the case sensitivity and character restrictions of the underlying file system. For example, Windows is case insensitive, but macOS and Linux aren't. * ASP.NET Core apps hosted in IIS use the [ASP.NET Core Module](xref:host-and-deploy/aspnet-core-module) to forward all requests to the app, including static file requests. The IIS static file handler isn't used and has no chance to handle requests. diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/Program.cs index 078d4f88e781..ca0cf394cf50 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFileAuth/Program.cs @@ -131,7 +131,7 @@ async Task SaveFileWithCustomFileName(IFormFile file, string fileSaveName) if (File.Exists(filePath)) { - return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}"); + return TypedResults.PhysicalFile(filePath, fileDownloadName: $"{fileName}"); } return TypedResults.NotFound("No file found with the supplied file name"); @@ -139,17 +139,21 @@ async Task SaveFileWithCustomFileName(IFormFile file, string fileSaveName) .WithName("GetFileByName") .RequireAuthorization("AuthenticatedUsers"); -// IFormFile uses memory buffer for uploading. For handling large file use streaming instead. -// https://learn.microsoft.com/aspnet/core/mvc/models/file-uploads#upload-large-files-with-streaming -app.MapPost("/files", async (IFormFile file, LinkGenerator linker, HttpContext context) => +app.MapPost("/files", + async (IFormFile file, LinkGenerator linker, HttpContext context) => { - // Don't rely on the file.FileName as it is only metadata that can be manipulated by the end-user - // Take a look at the `Utilities.IsFileValid` method that takes an IFormFile and validates its signature within the AllowedFileSignatures + // Don't rely on the file.FileName as it is only metadata that can be + // manipulated by the end-user. See the `Utilities.IsFileValid` method that + // takes an IFormFile and validates its signature within the + // AllowedFileSignatures - var fileSaveName = Guid.NewGuid().ToString("N") + Path.GetExtension(file.FileName); + var fileSaveName = Guid.NewGuid().ToString("N") + + Path.GetExtension(file.FileName); await SaveFileWithCustomFileName(file, fileSaveName); - context.Response.Headers.Append("Location", linker.GetPathByName(context, "GetFileByName", new { fileName = fileSaveName})); + context.Response.Headers.Append("Location", + linker.GetPathByName(context, "GetFileByName", + new { fileName = fileSaveName})); return TypedResults.Ok("File Uploaded Successfully!"); }) .RequireAuthorization("AdminsOnly"); diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/default.html b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/MyStaticFiles/defaultFiles/default.html similarity index 54% rename from aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/default.html rename to aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/MyStaticFiles/defaultFiles/default.html index 0e7651fcb76e..fe8894aa4252 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/default.html +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/MyStaticFiles/defaultFiles/default.html @@ -1,4 +1,4 @@ - + @@ -6,6 +6,6 @@

This is the default page

- default.html in wwwroot. comment out @*@page*@ in Pages\Index.cshtml + default.html in wwwroot/def comment out @*@page*@ in Pages\Index.cshtml - \ No newline at end of file + diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/MyStaticFiles/defaultFiles/image3.png b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/MyStaticFiles/defaultFiles/image3.png new file mode 100644 index 0000000000000000000000000000000000000000..82eb991a4e4e958a0f5f74293a7c289ecec174e7 GIT binary patch literal 6304 zcmb7}Wmr^Q+xJ0QYKC?gh7Rc%>5wid=`N*It|1+i9Ad~pP`VVPh8#j9rMrf18ITSM zL8N@S?)&-letMn{Yp=bIz0PCrwT^xKfB*AbF^2k@l=ngR@$m2{wYAiq;^E;_-Q6Qd ziSMorbv!k99lp;~O%=S#QSi>)fY4Q0PZdKkDnn&M*#ODEl}sCCO{b@G z&@1SstLwI(pPN0GD+?!o+i&GI`5CxNpwNY7i8^`eWXd)Hzf#1<=@|Aj_8hzHz zA&u#0?Bf*1)NzG+kEDlf31%(w2~V=7+{-^|J0BLoOe^d{tl|%5Qp}A_-9K63*Ezp6 z654(ue$d?1!a7nSabCb`ozkYmyC6ntscjXh3W(VM82*NyP#Km$iew|r1>yjN9TFU1 z1RGoYR%1814|74zGh`06C)R_B=5nYdm$px3$ zDqX@MsVI5>cldNnHgul{6u6>??jEc>VBV>46)ybwJMeCgx_n?Z^8ch+(L^k7^~mknH1R7L9{C|NBP9^rk?0XR-wnozYickpyJv7D=yN&%GHZ_#}Ph#?8ERRkDrlAT&qSZ@B!C)s&oF7JMFE9|(Fblzs%@dCO@LXwA4SFTFDGNa0{_J=%?+DiRGWkzRCf~9|ZzC{e7u@s0)arqqH)=KgwEf`8@*!YlR~~y3H4;3{CRmy``#5?aDW9t zagY{!p~5tl#hDlDP?Qi;k8=2xlx12y+bFZ^oMM84WbPnhPR#W}$;E`74{X2kmIXCuJi z*nzQ3O=-_)#c${v%!hHFJH~9$J>3EONE!ZYdXSHHRw8DHObCO6V~J~P-E(I2WHuve zO|-A~Z<}JMSeA5Kuc*zrA$;i?wc~tc3|}76RbccoUue%vX|N|` z=@Hj^SI*;v&+jC0tH4jq{s%>twOhS)waB8|`NU_w#_7v)yW89AW3aSaYzzVmtz=T# z)ijgymB}7&riw~?dSku?*W!BfB+_HAfE>wgL!ZU@&jxWith~o%6T@cpGHOUh(byF2 zhm7df%7Pt8wK&OZnh1C8lX9bt%*9@+Dyu+uE+@4ruivdB)Uj5$Q)Ka1NxZ z);Kgcoj7VGi%Bvz=nJ-LK=^wG7zlCe-vaxLu=9l;14LFD7izWBWtU*Ode?08yqI`b zZ@@&8!HtE9|D|@yW!vTp*5@5pD<2KQyS!Se`VaQHUvl1O-s8SyUA8(o&n0v*rXc=WZri7fWMiU$DKFA5Ua zx+C8E9mfaVTo=*4rs9O0mCA(Jcfzr&|3j-L{{I8BEamXZKRMFUGc=9(C4;_5wdzi% zIB(y<8QuM0AX(%Y$Wj0-->?%#K(f7AV{NK^DOS_s)wW>qbtE}&wvqV`+U8m2YJh95 zvdHi)shf=|&*D;Z+X9`*ICiko)tRK}+LMF5kdKr<1)u6-WL{mfx*r8R_s|Ahv+qTQ zAM46f;9#oQ`Pqp?&A$y+-ciQJ-Z|&HWGd)^%T+#dV&34j2QxQ_W`4}RFB~|)NRYDG z?w3oW3^SM^N8(;xJcNXgH9ssmlRFbPH3o=>XMbfGTI(ofw2=Qw{+@YTMxAT1`Q3eQ z7cfb&ox@o8IwVn{$s*-G0zfVE2yeg1eRAiB6BP=Vf2^mMW$J#O|J+5QM;gw63A4H+ z%)POGE-B$EHA$l`_W_A1Li$#A&3&mV%$pjDC!BHIzw(V9*nY72B(;u?T&3klJPgLu zC?NbT!itI|pF73C@O#_MRHn_kdZtkwLW9|I%*4M|n^DE2cWP4bZDZr7hW8_Oswtk&GZ6|t1UK|Dr{ znh{s1r3jbrO^=+HV zlIP}Xn>BUK4w`J16(7}ccu2mrR!~q446(8?(eXQ{xJrJd$T?tz10bS=@6j<3vA@6j zOG*HMI;K9ru1KYd8Cxei7yaRi8ij!Qa?;vKqzQj#61|qWx|Zvlt{rd5$=}vGYe?QvW1Q8u9HW;LEX#@u=Dx6#7%CKV&{gcV{GR(4 zRzPCAIfvP_l#P%ah{D6XxZ?eFjP_ngm=)QzD{7jh9dO9Yncrn$U1Xd~Uwzv+Mn}z`QR){bNLFH#XMN7unM6FC?=>Q$P_l)~ zahtCXV(AJ0?lVt)a=OiG{oCW`djUwshYCd_o=G<(SQxcMpTtu6?*5<9J;~BHkWnEL z08Wd*1uF`pp;m={-QU=`+3tu7PUkp|PWUfyn@XrcDTdd8@)Ow=D-z5l>}!ufZX+ikz8MSM+@l$oL4)efMxKjyY>wKiGeUh{e6JI2(;y%-fd zd`AP_&`C?2KnmP2?&)LpR82Z!&+N&U9vPjOO|BPp0)$S_fvDP7 zR}yGLm!ZL*Ad#)qjUN}zXU&e*I6*NA%x_KTFQZf8 zZ&Vk&`-@DaCjvc{*&I4Myza@dOqZFTcZ4HF_d}4|?K-4HOIOe?EUK6dg3Q(zppsoH z`%07Vm2Ty)hs0O2#rEvpuj2CMxxaR!zldbsAE_IEv&EfV(I#8^`k7PGeH`gvBT*P0 z8Oi02T!DNR_BoHyt=jd9OXO` z%3GE={+Piq?Tne_(Ij%R-7QjFRXQKIi!9qA1AJJ4ACxZs7I88bcMX4`qDkY|gy&C8 zp)!%=%z0r)#7>+c1Xl4NWuXRk_%%(I@`(MB3d&)_15$Ocu;?SADU6+-#y^Kl<5L^- zYpdi1-Ri**1raj#4r4 z4Sh0-6!{LK;<`@l`cXBFSCFsO0rC3lK#e-H*s$%b3)9;W7hT9*{`@Usv@h?yBRKTA zGVUrPMs0aXkpTi>B-Lj;w^H&Y4H?Ta0SC)n_)sYh@s$Y1gqJ?F+2>KoMdcKD0| zQ&MSc-)H~$jaa1wqJBA$_6by#AP6(0jUrT!fbU`bYKr*lwO09OL(v}Qz=Inz`ui&F zfIA^>_6JN?a4*!-DjdJbPxz;d-mAu!A8W{j{3D(bpy~y2xyrF(zli!*>-!pR^#Vt{ zn!&|853VgA|2k|QTot0W5njVdae(pH(%aN>0?f5s)`)<8#QIV(d?T;Y*_r(D@F{3T%C4fWtF_9X*?K z10>D4uNCG|+-nx}m19D2Wa)h!ZGRG~b(o631`wE0A3xqw`t@+%dG5PIRcC4^LuW8S zGvo|G8P{78!eeEt>1)B8pE0J%m}p`g#rlWTdf0(qsxmIRvOX<~nE^MfjJmZ5`e4W5B~oLyjPYYBhO=|G;`@8kHCo53 z`1y?AQJ(M6zlFP7sje_n|I$dG*v}LmYX>nKHZVUaUtV|24*x;Sq~!O&W;owSGIl%i zDV%P(AdVyrV=jK?p5L0i{%~Lz!57g*{MExgF3J$;>?3IJeu7thGB7m#wujU@ry;LX zyd~`UH#4Hx#XBSSHoVZS#P6adAj`P2hcy~#-$Mya#G^E;<(`uS?R{WciOM*>fQJ_tTC8n))vk71@O7v7qR6fn_{+Dz{ z+cnpx68R5?l0_glFB1;oXKfguY=(PztEBv zSW(gL0;Oyo$^Rl)P15Jmik3*)PS>V;^_4XqFd=Vj1gr|9REuYYD`C}rr*={gtfdtZ z#dNw^*{~o_OWiD+XBjZ*4j<@Iou9G8>kiob6k+7g@uRCNhuIG4t_-DWL-}w;xhzX4 z1;w2K@JneRB**$$KHD>Q>(KjPc^LokSbqb&AQ}I-M#@*u& zHfmNx#rAYF!P(A%9M;q^)cB_hH+Z2rW!eC+kI3EnRqr#8rD$4>@d9lQ?Ws zN6mC9h6UlTJC1NV%F3{Tv8!^>{U95nEb6X8HQEnn)qRe&jvbBGU3Y@9@IUPS+|J$` z)(eI(cyUc#meUs?n^V<1c9^7UL$8@;f74&VTL;rH~~6RlMTAx^|$!U9)6~wGnUW{dJsXXIf$#I`l}US z2D$aB4x*GW$QhGxJB9wSNlW-%OH!+O({336=f8pD9y9$mo{wK;GSPaw0S5O9Fwf$8 z`*x=+TS0jn&rjcyyts@lvh&S*CD^O|74%)*_!4xr*#x$eh);}U9Tr<*-Z-AD`$fYI ze%*T{EiFP8GUl>Q9(wb)`!A=UR1nf<5j~nP)EJ!H!gp7`?tf%4XL)q)p__En^n=vN z5b&Qu_dI(Dg6(t4c-xK8n%7-wM0Wgdb(<9Xmq57+GR%W^lDj)qz|&UOSF2QUK>RU literal 0 HcmV?d00001 diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs index 5d0a7306205e..6bb507555e82 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/Program.cs @@ -1,4 +1,4 @@ -#define DEFAULT // DEFAULT RR RH DB DF DF2 UFS UFS2 TREE FECTP NS MUL MULT2 +#define TREE // DEFAULT RR RH DB DF DF2 UFS UFS2 TREE FECTP NS MUL MULT2 // Test1 #if NEVER #elif DEFAULT @@ -142,6 +142,7 @@ app.Run(); // #elif DF // Default file +https://localhost:50921/def/ // var builder = WebApplication.CreateBuilder(args); @@ -160,7 +161,7 @@ app.UseDefaultFiles(); -app.MapStaticAssets(); +app.UseStaticFiles(); app.UseAuthorization(); app.MapDefaultControllerRoute().WithStaticAssets(); @@ -169,6 +170,7 @@ app.Run(); // #elif DF2 +// https://localhost:50921/def/ // var builder = WebApplication.CreateBuilder(args); @@ -190,7 +192,7 @@ options.DefaultFileNames.Add("mydefault.html"); app.UseDefaultFiles(options); -app.MapStaticAssets(); +app.UseStaticFiles(); app.UseAuthorization(); @@ -276,7 +278,7 @@ app.UseHttpsRedirection(); -app.MapStaticAssets(); +app.UseStaticFiles(); app.UseFileServer(new FileServerOptions { diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/default.html b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/default.html new file mode 100644 index 000000000000..fe8894aa4252 --- /dev/null +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/default.html @@ -0,0 +1,11 @@ + + + + + Default page + + +

This is the default page

+ default.html in wwwroot/def comment out @*@page*@ in Pages\Index.cshtml + + diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/index.html b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/index.html similarity index 54% rename from aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/index.html rename to aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/index.html index 538552f6c90c..6721b6699af8 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/index.html +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/index.html @@ -1,10 +1,10 @@ - + Index -

This is the index page in wwwroot.

+

This is the index page in wwwroot/def

- \ No newline at end of file + diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/myIndex.html b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/myIndex.html similarity index 54% rename from aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/myIndex.html rename to aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/myIndex.html index f45bd38a2b11..7659dc28db95 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/myIndex.html +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/myIndex.html @@ -1,10 +1,10 @@ - + myIndex -

This is the muyindex page in wwwroot.

+

This is the muyindex page in wwwroot/def

- \ No newline at end of file + diff --git a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/mydefault.html b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/mydefault.html similarity index 54% rename from aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/mydefault.html rename to aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/mydefault.html index 41db053a84f6..d5bef7f921a3 100644 --- a/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/mydefault.html +++ b/aspnetcore/fundamentals/static-files/samples/9.x/StaticFilesSample/wwwroot/def/mydefault.html @@ -1,10 +1,10 @@ - + myDefault -

This is the mydefault page in wwwroot.

+

This is the mydefault page in wwwroot/def

- \ No newline at end of file +