다음을 통해 공유


증분 마이그레이션에서 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}입니다. 경로를 ()로b.DisplayName = $"Blazor {route}"; 변경하는 Blazor {route} 줄은 경로를 명시적으로 등록된 것으로 식별합니다Blazor.
  • 경로 순서()((RouteEndpointBuilder)b).Order = -1;{page}를 설정하는 줄의 경우 기본적으로 경로 순서가 0 있습니다. Blazor 경로 우선 순위를 지정하도록 -1 순서가 변경되도록 경로 순서를 Blazor 설정합니다.

다음에서 사용하기 Blazor 위한 앱 등록을 업데이트합니다.Program.cs

- app.MapFallbackToPage("/_Host");
+ app.MapBlazorPages("/_Host");

이 시점에서 앱은 페이지에 대한 딥 링크를 포함하여 Yarp에 대한 Blazor 요청을 올바르게 라우팅해야 합니다.