diff --git a/src/Components/WebAssembly/DevServer/src/Server/Startup.cs b/src/Components/WebAssembly/DevServer/src/Server/Startup.cs
index 84bf7ac852..6b6c2a91f0 100644
--- a/src/Components/WebAssembly/DevServer/src/Server/Startup.cs
+++ b/src/Components/WebAssembly/DevServer/src/Server/Startup.cs
@@ -46,13 +46,13 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.DevServer.Server
app.UseBlazorDebugging();
+ app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
- endpoints.MapBlazorWebAssemblyApplication();
endpoints.MapFallbackToFile("index.html");
});
}
diff --git a/src/Components/WebAssembly/Server/src/ComponentsWebAssemblyApplicationBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/ComponentsWebAssemblyApplicationBuilderExtensions.cs
new file mode 100644
index 0000000000..eaf19da09e
--- /dev/null
+++ b/src/Components/WebAssembly/Server/src/ComponentsWebAssemblyApplicationBuilderExtensions.cs
@@ -0,0 +1,86 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Net.Mime;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.FileProviders;
+using Microsoft.Net.Http.Headers;
+
+namespace Microsoft.AspNetCore.Builder
+{
+ ///
+ /// Extensions for mapping Blazor WebAssembly applications.
+ ///
+ public static class ComponentsWebAssemblyApplicationBuilderExtensions
+ {
+ ///
+ /// Configures the application to serve Blazor WebAssembly framework files from the path . This path must correspond to a referenced Blazor WebAssembly application project.
+ ///
+ /// The .
+ /// The that indicates the prefix for the Blazor WebAssembly application.
+ /// The
+ public static IApplicationBuilder MapBlazorFrameworkFiles(this IApplicationBuilder builder, PathString pathPrefix)
+ {
+ if (builder is null)
+ {
+ throw new ArgumentNullException(nameof(builder));
+ }
+
+ var webHostEnvironment = builder.ApplicationServices.GetRequiredService();
+
+ var options = CreateStaticFilesOptions(webHostEnvironment.WebRootFileProvider);
+
+ builder.MapWhen(ctx => ctx.Request.Path.StartsWithSegments(pathPrefix, out var rest) && rest.StartsWithSegments("/_framework") && !rest.StartsWithSegments("/_framework/blazor.server.js"),
+ subBuilder =>
+ {
+ subBuilder.Use(async (ctx, next) =>
+ {
+ // At this point we mapped something from the /_framework
+ ctx.Response.Headers.Append(HeaderNames.CacheControl, "no-cache");
+ // This will invoke the static files middleware plugged-in below.
+ await next();
+ });
+
+ subBuilder.UseStaticFiles(options);
+ });
+
+ return builder;
+ }
+
+ ///
+ /// Configures the application to serve Blazor WebAssembly framework files from the root path "/".
+ ///
+ /// The .
+ /// The that indicates the prefix for the Blazor WebAssembly application.
+ /// The
+ public static IApplicationBuilder UseBlazorFrameworkFiles(this IApplicationBuilder applicationBuilder) =>
+ MapBlazorFrameworkFiles(applicationBuilder, default);
+
+ private static StaticFileOptions CreateStaticFilesOptions(IFileProvider webRootFileProvider)
+ {
+ var options = new StaticFileOptions();
+ options.FileProvider = webRootFileProvider;
+ var contentTypeProvider = new FileExtensionContentTypeProvider();
+ AddMapping(contentTypeProvider, ".dll", MediaTypeNames.Application.Octet);
+ // We unconditionally map pdbs as there will be no pdbs in the output folder for
+ // release builds unless BlazorEnableDebugging is explicitly set to true.
+ AddMapping(contentTypeProvider, ".pdb", MediaTypeNames.Application.Octet);
+
+ options.ContentTypeProvider = contentTypeProvider;
+
+ return options;
+ }
+
+ private static void AddMapping(FileExtensionContentTypeProvider provider, string name, string mimeType)
+ {
+ if (!provider.Mappings.ContainsKey(name))
+ {
+ provider.Mappings.Add(name, mimeType);
+ }
+ }
+ }
+}
diff --git a/src/Components/WebAssembly/Server/src/ComponentsWebAssemblyEndpointRouteBuilderExtensions.cs b/src/Components/WebAssembly/Server/src/ComponentsWebAssemblyEndpointRouteBuilderExtensions.cs
deleted file mode 100644
index d29212ff75..0000000000
--- a/src/Components/WebAssembly/Server/src/ComponentsWebAssemblyEndpointRouteBuilderExtensions.cs
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System;
-using System.Net.Mime;
-using Microsoft.AspNetCore.Hosting;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Routing;
-using Microsoft.AspNetCore.StaticFiles;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.FileProviders;
-using Microsoft.Net.Http.Headers;
-
-namespace Microsoft.AspNetCore.Builder
-{
- ///
- /// Extensions for mapping Blazor WebAssembly applications.
- ///
- public static class ComponentsWebAssemblyEndpointRouteBuilderExtensions
- {
- ///
- /// Maps a Blazor webassembly application to the .
- ///
- /// The .
- /// The that indicates the prefix for the Blazor application.
- /// The
- public static IEndpointConventionBuilder MapBlazorWebAssemblyApplication(this IEndpointRouteBuilder endpoints, PathString pathPrefix)
- {
- if (endpoints is null)
- {
- throw new ArgumentNullException(nameof(endpoints));
- }
-
- var webHostEnvironment = endpoints.ServiceProvider.GetRequiredService();
-
- var options = CreateStaticFilesOptions(webHostEnvironment.WebRootFileProvider);
- var appBuilder = endpoints.CreateApplicationBuilder();
-
- appBuilder.Use(async (ctx, next) =>
- {
- var endpoint = ctx.GetEndpoint();
- try
- {
- // Set the endpoint to null so that static files doesn't discard the path.
- ctx.SetEndpoint(null);
-
- if (ctx.Request.Path.StartsWithSegments(pathPrefix, out var rest) &&
- rest.StartsWithSegments("/_framework"))
- {
- // At this point we mapped something from the /_framework
- ctx.Response.Headers.Append(HeaderNames.CacheControl, "no-cache");
- }
-
- // This will invoke the static files middleware plugged-in below.
- await next();
-
- }
- finally
- {
- ctx.SetEndpoint(endpoint);
- }
- });
-
- appBuilder.UseStaticFiles(options);
-
- var conventionBuilder = endpoints.Map(
- $"{pathPrefix}/{{*path:file}}",
- appBuilder.Build());
-
- conventionBuilder.Add(builder =>
- {
- // Map this route with low priority so that it doesn't interfere with any other potential request.
- ((RouteEndpointBuilder)builder).Order = int.MaxValue - 100;
- });
-
- return conventionBuilder;
- }
-
- ///
- /// Maps a Blazor webassembly application to the root path of the application "/".
- ///
- /// The .
- /// The that indicates the prefix for the Blazor application.
- /// The
- public static IEndpointConventionBuilder MapBlazorWebAssemblyApplication(this IEndpointRouteBuilder endpoints) =>
- MapBlazorWebAssemblyApplication(endpoints, default);
-
- private static StaticFileOptions CreateStaticFilesOptions(IFileProvider webRootFileProvider)
- {
- var options = new StaticFileOptions();
- options.FileProvider = webRootFileProvider;
- var contentTypeProvider = new FileExtensionContentTypeProvider();
- AddMapping(contentTypeProvider, ".dll", MediaTypeNames.Application.Octet);
- // We unconditionally map pdbs as there will be no pdbs in the output folder for
- // release builds unless BlazorEnableDebugging is explicitly set to true.
- AddMapping(contentTypeProvider, ".pdb", MediaTypeNames.Application.Octet);
-
- options.ContentTypeProvider = contentTypeProvider;
-
- return options;
- }
-
- private static void AddMapping(FileExtensionContentTypeProvider provider, string name, string mimeType)
- {
- if (!provider.Mappings.ContainsKey(name))
- {
- provider.Mappings.Add(name, mimeType);
- }
- }
- }
-}
diff --git a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs
index a605d10ded..32dcb9d80f 100644
--- a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs
+++ b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs
@@ -33,11 +33,13 @@ namespace HostedInAspNet.Server
app.UseBlazorDebugging();
}
+ app.UseBlazorFrameworkFiles();
+ app.UseStaticFiles();
+
app.UseRouting();
app.UseEndpoints(endpoints =>
{
- endpoints.MapBlazorWebAssemblyApplication();
endpoints.MapFallbackToFile("index.html");
});
}
diff --git a/src/Components/WebAssembly/testassets/MonoSanity/Startup.cs b/src/Components/WebAssembly/testassets/MonoSanity/Startup.cs
index f777cbc4b3..3cf349e787 100644
--- a/src/Components/WebAssembly/testassets/MonoSanity/Startup.cs
+++ b/src/Components/WebAssembly/testassets/MonoSanity/Startup.cs
@@ -16,11 +16,11 @@ namespace MonoSanity
{
app.UseDeveloperExceptionPage();
app.UseFileServer(new FileServerOptions() { EnableDefaultFiles = true, });
+ app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
- endpoints.MapBlazorWebAssemblyApplication();
endpoints.MapFallbackToFile("index.html");
});
}
diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs
index 58c8fdb2c1..f7fdfab434 100644
--- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs
+++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Startup.cs
@@ -56,6 +56,9 @@ namespace Wasm.Authentication.Server
app.UseBlazorDebugging();
}
+ app.UseBlazorFrameworkFiles();
+ app.UseStaticFiles();
+
app.UseRouting();
app.UseAuthentication();
@@ -67,7 +70,6 @@ namespace Wasm.Authentication.Server
endpoints.MapControllers();
endpoints.MapRazorPages();
- endpoints.MapBlazorWebAssemblyApplication();
endpoints.MapFallbackToFile("index.html");
});
}
diff --git a/src/Components/test/testassets/TestServer/AuthenticationStartup.cs b/src/Components/test/testassets/TestServer/AuthenticationStartup.cs
index 261587c9ee..ca6648d133 100644
--- a/src/Components/test/testassets/TestServer/AuthenticationStartup.cs
+++ b/src/Components/test/testassets/TestServer/AuthenticationStartup.cs
@@ -49,12 +49,12 @@ namespace TestServer
// Mount the server-side Blazor app on /subdir
app.Map("/subdir", app =>
{
+ app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
- endpoints.MapBlazorWebAssemblyApplication();
endpoints.MapControllers();
endpoints.MapRazorPages();
endpoints.MapBlazorHub();
diff --git a/src/Components/test/testassets/TestServer/ClientStartup.cs b/src/Components/test/testassets/TestServer/ClientStartup.cs
index 4d4161b13d..b3a1633422 100644
--- a/src/Components/test/testassets/TestServer/ClientStartup.cs
+++ b/src/Components/test/testassets/TestServer/ClientStartup.cs
@@ -37,13 +37,12 @@ namespace TestServer
app.Map("/subdir", app =>
{
// Add it before to ensure it takes priority over files in wwwroot
+ app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
- endpoints.MapBlazorWebAssemblyApplication();
-
endpoints.MapRazorPages();
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
diff --git a/src/Components/test/testassets/TestServer/CorsStartup.cs b/src/Components/test/testassets/TestServer/CorsStartup.cs
index c6ed533955..8674037117 100644
--- a/src/Components/test/testassets/TestServer/CorsStartup.cs
+++ b/src/Components/test/testassets/TestServer/CorsStartup.cs
@@ -45,6 +45,7 @@ namespace TestServer
// Mount the server-side Blazor app on /subdir
app.Map("/subdir", app =>
{
+ app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
@@ -53,8 +54,6 @@ namespace TestServer
app.UseEndpoints(endpoints =>
{
- endpoints.MapBlazorWebAssemblyApplication();
-
endpoints.MapControllers();
endpoints.MapFallbackToFile("index.html");
});
diff --git a/src/Components/test/testassets/TestServer/InternationalizationStartup.cs b/src/Components/test/testassets/TestServer/InternationalizationStartup.cs
index 5f19ea80f5..ac2fa85eff 100644
--- a/src/Components/test/testassets/TestServer/InternationalizationStartup.cs
+++ b/src/Components/test/testassets/TestServer/InternationalizationStartup.cs
@@ -36,6 +36,7 @@ namespace TestServer
// Mount the server-side Blazor app on /subdir
app.Map("/subdir", app =>
{
+ app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRequestLocalization(options =>
@@ -54,8 +55,6 @@ namespace TestServer
app.UseRouting();
app.UseEndpoints(endpoints =>
{
- endpoints.MapBlazorWebAssemblyApplication();
-
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_ServerHost");
diff --git a/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs b/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs
index 9097914793..382ee8bf10 100644
--- a/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs
+++ b/src/Components/test/testassets/TestServer/StartupWithMapFallbackToClientSideBlazor.cs
@@ -33,12 +33,8 @@ namespace TestServer
// The client-side files middleware needs to be here because the base href in hardcoded to /subdir/
app.Map("/subdir", app =>
{
- app.UseRouting();
-
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapBlazorWebAssemblyApplication();
- });
+ app.UseBlazorFrameworkFiles();
+ app.UseStaticFiles();
});
// The calls to `Map` allow us to test each of these overloads, while keeping them isolated.
diff --git a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs b/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs
index 85573e7daf..e37ab2c340 100644
--- a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs
+++ b/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/content/ComponentsWebAssembly-CSharp/Server/Startup.cs
@@ -104,6 +104,7 @@ namespace ComponentsWebAssembly_CSharp.Server
}
#endif
+ app.UseBlazorFrameworkFiles();
app.UseStaticFiles();
app.UseRouting();
@@ -124,8 +125,6 @@ namespace ComponentsWebAssembly_CSharp.Server
endpoints.MapRazorPages();
#endif
endpoints.MapControllers();
-
- endpoints.MapBlazorWebAssemblyApplication();
endpoints.MapFallbackToFile("index.html");
});
}