From 9b8e93c67beef8fd629ebc15649bf65efc5bc351 Mon Sep 17 00:00:00 2001 From: NetherGranite Date: Sun, 29 Mar 2026 00:59:53 -0600 Subject: [PATCH 1/2] Restore the static file endpoints for `blazor.web.js` and `blazor.server.js` Additionally adapts the code to changes to the code's context. --- .../RazorComponentEndpointDataSource.cs | 44 ++++++++++++++++++- .../ComponentEndpointConventionBuilder.cs | 7 ++- ...ComponentEndpointRouteBuilderExtensions.cs | 36 ++++++++++++++- 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs index 7ce2a54419b0..bc59642139df 100644 --- a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs +++ b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs @@ -1,15 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Buffers; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Components.Discovery; using Microsoft.AspNetCore.Components.Endpoints.Infrastructure; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; +using Microsoft.AspNetCore.Routing.Patterns; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Primitives; using static Microsoft.AspNetCore.Internal.LinkerFlags; @@ -184,6 +187,7 @@ private void UpdateEndpoints() private void AddBlazorWebEndpoints(List endpoints) { List blazorWebEndpoints = [ + ..GetBlazorWebJsEndpoint(_endpointRouteBuilder), OpaqueRedirection.GetBlazorOpaqueRedirectionEndpoint()]; foreach (var endpoint in blazorWebEndpoints) @@ -202,6 +206,44 @@ private void AddBlazorWebEndpoints(List endpoints) } } + private static IEnumerable GetBlazorWebJsEndpoint(IEndpointRouteBuilder endpoints) + { + var app = endpoints.CreateApplicationBuilder(); + + var webHostEnvironment = endpoints.ServiceProvider.GetRequiredService(); + + var options = new StaticFileOptions + { + FileProvider = webHostEnvironment.WebRootFileProvider, + OnPrepareResponse = CacheHeaderSettings.SetCacheHeaders + }; + + app.Use(next => context => + { + // Set endpoint to null so the static files middleware will handle the request. + context.SetEndpoint(null); + + return next(context); + }); + + app.UseStaticFiles(options); + + var requestDelegate = app.Build(); + + var blazorWebJsBuilder = new RouteEndpointBuilder( + requestDelegate, + RoutePatternFactory.Parse("/_framework/blazor.web.js"), + int.MinValue) + { + DisplayName = "Blazor web static files" + }; + + var allowedHttpMethods = new HttpMethodMetadata([HttpMethods.Get, HttpMethods.Head]); + blazorWebJsBuilder.Metadata.Add(allowedHttpMethods); + + return [blazorWebJsBuilder]; + } + public override IChangeToken GetChangeToken() { Initialize(); diff --git a/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs b/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs index dd26550d25f6..402f8cbc2781 100644 --- a/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs +++ b/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs @@ -11,15 +11,18 @@ public sealed class ComponentEndpointConventionBuilder : IHubEndpointConventionB private readonly IEndpointConventionBuilder _hubEndpoint; private readonly IEndpointConventionBuilder _disconnectEndpoint; private readonly IEndpointConventionBuilder _jsInitializersEndpoint; + private readonly IEndpointConventionBuilder _blazorEndpoint; internal ComponentEndpointConventionBuilder( IEndpointConventionBuilder hubEndpoint, IEndpointConventionBuilder disconnectEndpoint, - IEndpointConventionBuilder jsInitializersEndpoint) + IEndpointConventionBuilder jsInitializersEndpoint, + IEndpointConventionBuilder blazorEndpoint) { _hubEndpoint = hubEndpoint; _disconnectEndpoint = disconnectEndpoint; _jsInitializersEndpoint = jsInitializersEndpoint; + _blazorEndpoint = blazorEndpoint; } /// @@ -31,6 +34,7 @@ public void Add(Action convention) _hubEndpoint.Add(convention); _disconnectEndpoint.Add(convention); _jsInitializersEndpoint.Add(convention); + _blazorEndpoint.Add(convention); } /// @@ -39,5 +43,6 @@ public void Finally(Action finalConvention) _hubEndpoint.Finally(finalConvention); _disconnectEndpoint.Finally(finalConvention); _jsInitializersEndpoint.Finally(finalConvention); + _blazorEndpoint.Finally(finalConvention); } } diff --git a/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs b/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs index 26cca2322d0f..b1ce625f2abf 100644 --- a/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs +++ b/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs @@ -2,9 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Components.Server; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Connections; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.SignalR; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Builder; @@ -85,6 +89,36 @@ public static ComponentEndpointConventionBuilder MapBlazorHub( endpoints.CreateApplicationBuilder().UseMiddleware().Build()) .WithDisplayName("Blazor initializers"); - return new ComponentEndpointConventionBuilder(hubEndpoint, disconnectEndpoint, jsInitializersEndpoint); + var blazorEndpoint = GetBlazorEndpoint(endpoints); + + return new ComponentEndpointConventionBuilder(hubEndpoint, disconnectEndpoint, jsInitializersEndpoint, blazorEndpoint); + } + + private static IEndpointConventionBuilder GetBlazorEndpoint(IEndpointRouteBuilder endpoints) + { + var webHostEnvironment = endpoints.ServiceProvider.GetRequiredService(); + + var options = new StaticFileOptions + { + FileProvider = webHostEnvironment.WebRootFileProvider, + OnPrepareResponse = CacheHeaderSettings.SetCacheHeaders + }; + + var app = endpoints.CreateApplicationBuilder(); + app.Use(next => context => + { + // Set endpoint to null so the static files middleware will handle the request. + context.SetEndpoint(null); + + return next(context); + }); + app.UseStaticFiles(options); + + var blazorEndpoint = endpoints.Map("/_framework/blazor.server.js", app.Build()) + .WithDisplayName("Blazor static files"); + + blazorEndpoint.Add((builder) => ((RouteEndpointBuilder)builder).Order = int.MinValue); + + return blazorEndpoint; } } From 314fa643740cc1fa8d6a721ddb6ee9032b32bec3 Mon Sep 17 00:00:00 2001 From: NetherGranite Date: Sun, 29 Mar 2026 02:03:06 -0600 Subject: [PATCH 2/2] Add dummy static asset guards to the restored framework file endpoints --- .../src/Builder/RazorComponentEndpointDataSource.cs | 7 +++++++ .../src/Builder/ComponentEndpointConventionBuilder.cs | 8 ++++---- .../Builder/ComponentEndpointRouteBuilderExtensions.cs | 8 +++++++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs index bc59642139df..1d4df53b51ed 100644 --- a/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs +++ b/src/Components/Endpoints/src/Builder/RazorComponentEndpointDataSource.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; +using Microsoft.AspNetCore.StaticAssets.Infrastructure; using Microsoft.AspNetCore.StaticFiles; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Primitives; @@ -208,6 +209,12 @@ private void AddBlazorWebEndpoints(List endpoints) private static IEnumerable GetBlazorWebJsEndpoint(IEndpointRouteBuilder endpoints) { + // TODO: Is this how we want to check? + if (StaticAssetsEndpointDataSourceHelper.HasStaticAssetsDataSource(endpoints)) + { + return []; + } + var app = endpoints.CreateApplicationBuilder(); var webHostEnvironment = endpoints.ServiceProvider.GetRequiredService(); diff --git a/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs b/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs index 402f8cbc2781..a26d2621cd15 100644 --- a/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs +++ b/src/Components/Server/src/Builder/ComponentEndpointConventionBuilder.cs @@ -11,13 +11,13 @@ public sealed class ComponentEndpointConventionBuilder : IHubEndpointConventionB private readonly IEndpointConventionBuilder _hubEndpoint; private readonly IEndpointConventionBuilder _disconnectEndpoint; private readonly IEndpointConventionBuilder _jsInitializersEndpoint; - private readonly IEndpointConventionBuilder _blazorEndpoint; + private readonly IEndpointConventionBuilder? _blazorEndpoint; internal ComponentEndpointConventionBuilder( IEndpointConventionBuilder hubEndpoint, IEndpointConventionBuilder disconnectEndpoint, IEndpointConventionBuilder jsInitializersEndpoint, - IEndpointConventionBuilder blazorEndpoint) + IEndpointConventionBuilder? blazorEndpoint) { _hubEndpoint = hubEndpoint; _disconnectEndpoint = disconnectEndpoint; @@ -34,7 +34,7 @@ public void Add(Action convention) _hubEndpoint.Add(convention); _disconnectEndpoint.Add(convention); _jsInitializersEndpoint.Add(convention); - _blazorEndpoint.Add(convention); + _blazorEndpoint?.Add(convention); } /// @@ -43,6 +43,6 @@ public void Finally(Action finalConvention) _hubEndpoint.Finally(finalConvention); _disconnectEndpoint.Finally(finalConvention); _jsInitializersEndpoint.Finally(finalConvention); - _blazorEndpoint.Finally(finalConvention); + _blazorEndpoint?.Finally(finalConvention); } } diff --git a/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs b/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs index b1ce625f2abf..8c0f2f97d3cc 100644 --- a/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs +++ b/src/Components/Server/src/Builder/ComponentEndpointRouteBuilderExtensions.cs @@ -94,8 +94,14 @@ public static ComponentEndpointConventionBuilder MapBlazorHub( return new ComponentEndpointConventionBuilder(hubEndpoint, disconnectEndpoint, jsInitializersEndpoint, blazorEndpoint); } - private static IEndpointConventionBuilder GetBlazorEndpoint(IEndpointRouteBuilder endpoints) + private static IEndpointConventionBuilder? GetBlazorEndpoint(IEndpointRouteBuilder endpoints) { + // TODO: Is this how we want to check? If so, do we want to add the necessary reference to Microsoft.AspNetCore.StaticAssets? + if (false /*StaticAssetsEndpointDataSourceHelper.HasStaticAssetsDataSource(endpoints)*/) + { + return null; + } + var webHostEnvironment = endpoints.ServiceProvider.GetRequiredService(); var options = new StaticFileOptions