项目

迁移至 Blazor Web 应用

.NET 8 中的 ASP.NET Blazor 允许您使用一个强大的组件模型来处理所有 Web UI 需求,包括服务器端渲染、客户端渲染、流式渲染、渐进式增强等等!

ABP v8.2.x 支持新的 Blazor Web App 模板。在本指南中,我们将介绍新的 Blazor Web App 模板中的一些变化和特性。

创建新的 Blazor Web 应用

请确保您已安装 8.2.x 版本的 ABP CLI。

您可以使用 abp new BookStore -t app -u blazor-webapp 命令创建一个新的 Blazor Web 应用。-u blazor-webapp 选项用于选择 Blazor Web App 模板。

当然,您也可以创建 Blazor WASM 和 Blazor Server 应用程序。我们已将其更改为使用新的 Blazor Web App 模式:

abp new BookStore -t app -u blazor
abp new BookStore -t app -u blazor-server

渲染模式

模板项目在 App.razor 组件中为不同类型的项目使用不同的渲染模式。

类型 渲染模式
WASM InteractiveWebAssembly(prerender: false)
Server InteractiveServer
WebApp InteractiveAuto

新 Blazor Web App 模板的关键变化

新的 Web App 模板有两个项目,每个都包含一个 ABP 模块 体系。

  • MyCompanyName.MyProjectName.Blazor.WebApp
  • MyCompanyName.MyProjectName.Blazor.WebApp.Client

MyCompanyName.MyProjectName.Blazor.WebApp

Blazor.WebApp 是启动项目,Blazor.WebApp 项目中有一个 App.razor 组件,它是 Blazor 应用程序的根组件。

它与常规的 Blazor 服务器项目之间的主要区别在于:

  1. 您需要在 AbpAspNetCoreComponentsWebOptions 中将 IsBlazorWebApp 进行 PreConfiguretrue
public override void PreConfigureServices(ServiceConfigurationContext context)
{
    PreConfigure<AbpAspNetCoreComponentsWebOptions>(options =>
    {
        options.IsBlazorWebApp = true;
    });
}
  1. 向容器中添加相关服务。通过配置 AbpRouterOptions,将 MyProjectNameBlazorClientModule 的程序集添加到 AdditionalAssemblies 中:
public override void ConfigureServices(ServiceConfigurationContext context)
{
    // 向容器中添加服务。
    context.Services.AddRazorComponents()
        .AddInteractiveServerComponents()
        .AddInteractiveWebAssemblyComponents();

    Configure<AbpRouterOptions>(options =>
    {
        options.AppAssembly = typeof(MyProjectNameBlazorModule).Assembly;
        options.AdditionalAssemblies.Add(typeof(MyProjectNameBlazorClientModule).Assembly);
    });
}
  1. OnApplicationInitialization 方法中添加 UseAntiforgery 中间件以及 MapRazorComponents/AddInteractiveServer/WebAssemblyRenderMode/AddAdditionalAssemblies
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
    var env = context.GetEnvironment();
    var app = context.GetApplicationBuilder();
    // ...

    app.UseAntiforgery();
    app.UseAuthorization();

    app.UseConfiguredEndpoints(builder =>
    {
        builder.MapRazorComponents<App>()
            .AddInteractiveServerRenderMode()
            .AddInteractiveWebAssemblyRenderMode()
            .AddAdditionalAssemblies(builder.ServiceProvider.GetRequiredService<IOptions<AbpRouterOptions>>().Value.AdditionalAssemblies.ToArray());
    });
}

MyCompanyName.MyProjectName.Blazor.WebApp.Client

Blazor.WebApp.Client 项目中有一个 Routers.razor 组件,App.razor 组件会使用它。

它与常规的 Blazor WASM 项目之间的主要区别在于:

  1. 您需要在 AbpAspNetCoreComponentsWebOptions 中将 IsBlazorWebApp 进行 PreConfiguretrue
public override void PreConfigureServices(ServiceConfigurationContext context)
{
    PreConfigure<AbpAspNetCoreComponentsWebOptions>(options =>
    {
        options.IsBlazorWebApp = true;
    });
}
  1. 使用 AddBlazorWebAppServices 来替换 Authentication 代码:
private static void ConfigureAuthentication(WebAssemblyHostBuilder builder)
{
    builder.Services.AddBlazorWebAppServices();
}
  1. 移除 builder.RootComponents.Add<App>("#ApplicationContainer"); 代码。

MyCompanyName.MyProjectName.Blazor.WebApp.Tiered 和 MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.Client

分层项目与 WebApp 项目相同,但身份验证配置不同。

我们需要将 access_token 共享到 Client 项目。

MyCompanyName.MyProjectName.Blazor.WebApp.TieredApp.razor 中添加如下代码块:

@code{
    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    [Inject]
    private PersistentComponentState PersistentComponentState { get; set; }

    private string? Token { get; set; } = default!;

    protected override async Task OnInitializedAsync()
    {
        if (HttpContext.User?.Identity?.IsAuthenticated == true)
        {
            Token = await HttpContext.GetTokenAsync("access_token");
        }

        PersistentComponentState.RegisterOnPersisting(OnPersistingAsync, RenderMode.InteractiveWebAssembly);
    }

    async Task OnPersistingAsync()
    {
        if (!Token.IsNullOrWhiteSpace())
        {
            PersistentComponentState.PersistAsJson(PersistentAccessToken.Key, new PersistentAccessToken
            {
                AccessToken = Token
            });
        }

        await Task.CompletedTask;
    }
}

MyCompanyName.MyProjectName.Blazor.WebApp.Tiered.ClientMyProjectNameBlazorClientModule 中添加 ConfigureAuthentication,如下所示:

private static void ConfigureAuthentication(WebAssemblyHostBuilder builder)
{
    builder.Services.AddBlazorWebAppTieredServices();
}

ABP Bundle

您需要在 MyCompanyName.MyProjectName.Blazor.WebApp.Client 项目的 appsettings.json 文件中将 IsBlazorWebAppInteractiveAuto 设置为 true

{
  "AbpCli": {
    "Bundle": {
      "Mode": "BundleAndMinify", /* 选项:None, Bundle, BundleAndMinify */
      "Name": "global",
      "IsBlazorWebApp": true,
      "InteractiveAuto": true,
      "Parameters": {

      }
    }
  }
}

对于 Blazor WASM 和 Blazor Server 应用程序,您需要将 IsBlazorWebApp 设置为 true,并且不需要更改 InteractiveAuto

{
  "AbpCli": {
    "Bundle": {
      "Mode": "BundleAndMinify", /* 选项:None, Bundle, BundleAndMinify */
      "Name": "global",
      "IsBlazorWebApp": true,
      "Parameters": {

      }
    }
  }
}

然后在 MyCompanyName.MyProjectName.Blazor.WebApp.Client 项目下运行 abp bundle 命令以生成 global.cssglobal.js 文件。

故障排除

如果在迁移过程中遇到任何问题,请创建一个新的模板项目,并比较新旧项目之间的差异。

参考

在本文档中