-
Notifications
You must be signed in to change notification settings - Fork 10.4k
[Blazor] Move to MapBlazorWebAssemblyApplication #19147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// 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 | ||
{ | ||
/// <summary> | ||
/// Extensions for mapping Blazor WebAssembly applications. | ||
/// </summary> | ||
public static class ComponentsWebAssemblyEndpointRouteBuilderExtensions | ||
{ | ||
/// <summary> | ||
/// Maps a Blazor webassembly application to the <paramref name="pathPrefix"/>. | ||
/// </summary> | ||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param> | ||
/// <param name="pathPrefix">The <see cref="PathString"/> that indicates the prefix for the Blazor application.</param> | ||
/// <returns>The <see cref="IEndpointConventionBuilder"/></returns> | ||
public static IEndpointConventionBuilder MapBlazorWebAssemblyApplication(this IEndpointRouteBuilder endpoints, PathString pathPrefix) | ||
{ | ||
if (endpoints is null) | ||
{ | ||
throw new ArgumentNullException(nameof(endpoints)); | ||
} | ||
|
||
var webHostEnvironment = endpoints.ServiceProvider.GetRequiredService<IWebHostEnvironment>(); | ||
|
||
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to check, what are the possible scenarios where this might conflict unexpectedly with other things a developer might be doing? Are they safe to have their own separate Not saying it's the wrong design - just want to get my understanding right. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, you can have your own static files middleware and except for the case they are being mapped into the same subpath (or to "/") this should not interfere. In the future, I want to flow the paths into the host so that it can map exactly the files the blazor app is meant to serve and nothing else. At that point there's no room for ever conflicting with the static files middleware. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the default "hosted" template case, if someone puts As long as it's not hugely disruptive it's probably OK for preview2, but just checking we know what to expect.
Totally makes sense as a future enhancement. |
||
|
||
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; | ||
} | ||
|
||
/// <summary> | ||
/// Maps a Blazor webassembly application to the root path of the application "/". | ||
/// </summary> | ||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param> | ||
/// <param name="pathPrefix">The <see cref="PathString"/> that indicates the prefix for the Blazor application.</param> | ||
/// <returns>The <see cref="IEndpointConventionBuilder"/></returns> | ||
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); | ||
} | ||
} | ||
} | ||
} |
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.