増分移行で Yarp を使用して ASP.NET Core Blazor Server サポートを有効にする
Yarp を Blazor Server アプリに追加する場合、両方ともアプリの要求ルーティングのフォールバック ルートとして機能しようとします。 Blazor または Yarp が任意でルーティングを処理します。これは、Blazor のディープ リンクなどのシナリオが失敗する可能性があることを意味します。 これは、今年後半の .NET 8 リリースで修正される予定です。 ASP.NET Core 6.0 および 7.0 への移行の場合は、この記事のガイダンスに従って、正しい要求ルーティングを実現するように Blazor のエンドポイントをマップします。
次のルート ビルダー拡張機能クラスをプロジェクトに追加します。
BlazorEndpointRouteBuilderExtensions.cs
:
using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Routing;
public static class BlazorEndpointRouteBuilderExtensions {
public static IEndpointConventionBuilder MapBlazorPages(
this IEndpointRouteBuilder endpoints, string page)
{
var assembly = Assembly.GetEntryAssembly();
if (assembly is null)
{
throw new InvalidOperationException("No entry assembly available.");
}
return endpoints.MapBlazorPages(page, assembly);
}
public static IEndpointConventionBuilder MapBlazorPages(
this IEndpointRouteBuilder endpoints, string page,
params Assembly[] assemblies)
{
ArgumentNullException.ThrowIfNull(assemblies);
var builder = new BlazorEndpointConventionBuilder();
foreach (var route in GetRoutes(assemblies))
{
var conventionBuilder = endpoints.MapFallbackToPage(route, page);
conventionBuilder.Add(b =>
{
b.DisplayName = $"Blazor {route}";
((RouteEndpointBuilder)b).Order = -1;
});
builder.Add(conventionBuilder);
}
return builder;
}
private static IEnumerable<string> GetRoutes(Assembly[] assemblies)
{
foreach (var assembly in assemblies)
{
foreach (var type in assembly.GetTypes())
{
if (typeof(IComponent).IsAssignableFrom(type))
{
foreach (var attribute in
type.GetCustomAttributes(typeof(RouteAttribute)))
{
if (attribute is RouteAttribute { Template: { } route })
{
yield return route;
}
}
}
}
}
}
private sealed class BlazorEndpointConventionBuilder : IEndpointConventionBuilder {
private readonly List<IEndpointConventionBuilder> builders = new();
public void Add(IEndpointConventionBuilder builder)
{
builders.Add(builder);
}
void IEndpointConventionBuilder.Add(Action<EndpointBuilder> convention)
{
foreach (var builder in builders)
{
builder.Add(convention);
}
}
#if NET7_0_OR_GREATER
void IEndpointConventionBuilder.Finally(
Action<EndpointBuilder> finalConvention)
{
foreach (var builder in builders)
{
builder.Finally(finalConvention);
}
}
#endif
}
}
上のコードでは以下の操作が行われます。
- EndpointBuilder.DisplayName の既定値は
Fallback {route}
です。 これをBlazor {route}
(b.DisplayName = $"Blazor {route}";
) に変更する行は、Blazor ルートを明示的に登録済みとして識別します。 - ルート順序 (
((RouteEndpointBuilder)b).Order = -1;
) を設定する行の場合、既定では{page}
に0
のルート順序があります。 Blazor ルートの順序を-1
に設定すると、Blazor ルートの優先順位を指定するように順序が変更されます。
Program.cs
で Blazor を使用するためのアプリの登録を更新します。
- app.MapFallbackToPage("/_Host");
+ app.MapBlazorPages("/_Host");
この時点で、アプリは、ページに対するディープ リンクを含め、Blazor と Yarp に対して要求を正しくルーティングする必要があります。
GitHub で Microsoft と共同作業する
このコンテンツのソースは GitHub にあります。そこで、issue や pull request を作成および確認することもできます。 詳細については、共同作成者ガイドを参照してください。
ASP.NET Core