开发者问题收集

作为 Blazor 服务器端运行 Blazor WASM

2020-09-06
4809

问题

Blazor WASM 本来可以比 Blazor Server-Side 更容易被接受,并且不存在其在开发方面的缺点。目前,Blazor WASM 不支持功能齐全的调试体验,并且启动速度非常慢。这比使用 Blazor Server-Side 更能减慢开发速度。不过我个人认为,调试体验比启动速度慢更能减慢开发速度。

建议的解决方案

NOTE: I included the "proposed" word in there because I'm not sure about the downsides that this solution can cause, so feel free to comment on my answer below.

解决方案是简单地创建一个额外的 Blazor Server-Side 项目,然后将 Blazor WASM 项目引用到 Blazor Server-Side 项目。之后,对 Blazor Server-Side 的 Startup_Host.cshtml 进行一些调整,以正确使用 Blazor WASM razor 文件和 wwwroot 文件。请参阅下面我提出的答案,以获得该解决方案的逐步说明。

简而言之,此解决方案仅添加和配置 Blazor 服务器端项目, 无需 对 Blazor WASM 项目进行 任何更改 任何重大代码重复

2个回答

NOTE: In this example, I'm using Visual Studio 2019 16.7.2 and the version of the templates are currently at 3.1.8

  1. 创建一个 Blazor WASM 项目。ASP.NET Core Hosted 或 Standalone 选项都可以正常工作,但它们将具有不同的配置,稍后将进行讨论。其余选项不会产生任何影响。在此示例中,我将使用 ASP.NET Core Hosted 来解释有关 API 控制器的信息。之后还要创建 Blazor 服务器端项目。

    创建 ASP.NET Core 托管 Blazor WASM 项目 创建 Blazor 服务器端项目


  1. 截至目前,您的项目结构应类似于下面的第一个屏幕截图。

    删除下面第二个屏幕截图中显示的 Blazor 服务器端项目中突出显示的项目。

    在此处输入图像描述 要从 Blazor 服务器端项目中删除的项目


  1. 将 Blazor WASM 项目引用到 Blazor 服务器端项目。

    • ASP.NET Core Hosted - 引用 BlazorWasm.ClientBlazorWasm.Server 项目。
    • Standalone - 按原样引用单个 Blazor WASM 项目。

  1. 转到 Blazor 服务器端项目的 Startup 类。在 ConfigureServices() 中,删除 WeatherForecastService 以及 BlazorServer.Data 命名空间,然后为 HttpClient 添加服务,供 Blazor WASM 项目中的 razor 文件使用。

    services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(sp.GetRequiredService<NavigationManager>().BaseUri) });
    

    注意 在生产中,我不建议创建 HttpClient 的实例。请改用 IHttpClientFactory 。访问此文章 使用 IHttpClientFactory 实现弹性 HTTP 请求

    对于 ASP.NET Core WASM 项目

    Configure() 中,映射控制器的端点。这将使用 X.Server / BlazorWasm.Server 项目中的控制器。

    app.UseEndpoints(endpoints =>
    {
    endpoints.MapControllers();
    ...
    });
    

  1. 转到 Blazor 服务器端项目的 /Pages 文件夹中的 _Host.cshtml 。将 css/site.css 的引用更改为 css/app.css ,因为 Blazor WASM 项目的主 css 文件的文件名不同。

    <link href="css/site.css" rel="stylesheet" /> <!-- Previous -->
    <link href="css/app.css" rel="stylesheet" /> <!-- New -->
    

  1. 最后,在 component 标记的 type 属性中更改 App ,并引用 Blazor WASM 项目中的 App razor 类文件。在此示例中,在 BlazorWasm.Client 项目中找到 App 类:

    <component type="typeof(App)" render-mode="ServerPrerendered" /> <!-- Previous -->
    <component type="typeof(BlazorWasm.Client.App)" render-mode="ServerPrerendered" /> <!-- New -->
    

就是这样!当您运行 Blazor 服务器端项目时,它应该会加载,而不会出现“正在加载...”文本。

  • 未对 Blazor WASM 项目进行任何更改,并且未进行任何重大代码重复。
  • 唯一需要更改的是引用和 launchSettings.json & appsettings.json
  • 至于 Startup 中 Blazor 服务器端的配置,您只需在 Blazor WASM 项目中创建扩展方法并在 Blazor 服务器端项目中使用它们即可。

NOTE: I honestly think this is ideally(?) only for debugging during development since the WASM razor files won't fully utilize the capability of a true Blazor Server-Side because it would still use HTTP Requests.

Blazor WASM 项目作为 Blazor 服务器端运行


希望在下面得到反馈!:DD

DaaWaan
2020-09-06

我建议采用另一种方法。从服务器项目引用 WASM 项目还有其他缺点,但我个人认为这是一种架构上不够优雅的解决方案。

Blazor Server 和 WASM 在一些关键领域有所不同:

  1. 身份验证:Blazor 服务器允许您在运行时自定义对特定区域的访问。在 WASM 中,授权一次性完成,应用程序代码将完整发送。
  2. 数据库访问:Blazor 服务器允许直接访问 EF 核心实体(因为代码仅在服务器上执行)。在 Blazor 中,实际上不可能直接访问任何数据库。这也是非常不鼓励的,因为您会将连接字符串发送到客户端。因此,您需要编写一个单独的 Web API 来访问数据。 3. 设置文件:您可以在服务器端 Blazor 中拥有任意数量的设置文件。客户端 Blazor 默认仅加载 appsettings.json。需要一种特殊机制来包含多个 .json 文件。

因此,对于大多数应用程序(当然是需要数据库访问的应用程序),您将无法在 WASM 和服务器端之间共享 100% 的代码库。

您应该这样做:

  1. 对于上面提到的要点(身份验证,但主要是数据库访问),创建数据访问服务依赖项(例如 IDataAccessLayer)。 一个实现将直接访问数据库(用于服务器端) 另一个实现将通过 HttpClient 访问数据库(用于 blazor WASM)。

  2. 现在,将您的整个应用程序放入 RCL 中。将其称为“BlazorAppRCL”。此 RCL 显然没有 Startup.cs 和 Program.cs

  3. 为服务器和客户端特定数据库访问实现创建一个项目

  4. 现在,您有以下一组项目:

对于服务器端: BlazorServer(仅具有设置 + Program.cs + Startup.cs)。它指的是 RCL + 服务器特定的 IDataAccessLayer 实现

对于托管 WASM: BlazorWebAPI:对于数据库访问,它具有访问数据库的 API BlazorClientDAL:WASM 特定的 IDataAccessLayer 实现 BlazorWASM:Blazor WASM 项目 所有这三个都引用您的 BlazorAppRCL。

关键是使用 DI/控制反转模式来解决 WASM 和服务器之间的分歧。 这样,您就可以同时拥有 WASM 实例和服务器实例,并且代码差异最小。请注意,WASM WebAPI 可以简单地使用服务器端 Blazor 的 IDataAccessLayer 实现。因此,除了 API 相关开销之外,不需要额外的编码。

Mayur Ekbote
2021-10-13