将Blazor WASM作为Blazor服务器端运行

9

问题

如果不考虑开发方面的缺点,Blazor WASM本应比Blazor Server-Side更易被接受。目前,Blazor WASM不支持完整的调试体验,并且启动速度非常慢,这比使用Blazor Server-Side使开发变慢得多。尽管我个人认为,调试体验比启动速度更影响开发效率。

解决方案

注意:我在这里包含了“建议”一词,因为我不确定这种解决方案可能会带来什么不利影响,所以请随时在我的下面回答中发表评论。

解决方案很简单,只需创建一个额外的 Blazor Server-Side 项目,然后将 Blazor WASM 项目引用到 Blazor Server-Side 项目中。之后,在 Blazor Server-Side 的 Startup_Host.cshtml 中添加一些调整,以正确使用 Blazor WASM razor 文件和 wwwroot 文件。请参阅下面的我的建议答案,以获得有关此解决方案的逐步说明。

简单来说,这个解决方案只是添加并配置 Blazor Server-Side 项目,而不需要对 Blazor WASM 项目进行任何重大的代码重复或更改

2个回答

10

注意: 在本例中,我使用的是 Visual Studio 2019 16.7.2,模板版本目前为 3.1.8

  1. 创建一个 Blazor WASM 项目。使用 ASP.NET Core Hosted 或 Standalone 都可以,但它们将在稍后有不同的配置,这将在下面讨论。其他选项不会有任何影响。在本例中,我将选择 ASP.NET Core Hosted,以便稍后讲解如何使用 API 控制器。之后还要创建 Blazor Server-Side 项目。

    创建 ASP.NET Core Hosted Blazor WASM 项目 创建 Blazor Server-Side 项目


  1. 此时,您的项目结构应类似于下面第一张截图。

    删除 Blazor Server-Side 项目中第二张截图中突出显示的项目。

    输入图像描述 从 Blazor Server-Side 项目中删除的项目


  1. 将 Blazor WASM 项目引用到 Blazor Server-Side 项目中。

    • ASP.NET Core Hosted - 引用 BlazorWasm.ClientBlazorWasm.Server 两个项目。
    • Standalone - 直接引用单个 Blazor WASM 项目。

  1. 转到 Blazor Server-Side 项目的 Startup 类。在 ConfigureServices() 中,删除 WeatherForecastServiceBlazorServer.Data 命名空间,然后添加一个服务,用于供来自 Blazor WASM 项目的 razor 文件使用的 HttpClient

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 Server-Side项目的/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剃刀类文件。在此示例中,App类位于BlazorWasm.Client项目中:

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

完成了!运行Blazor Server-Side项目时,不应该加载“正在加载…”文本。

  • 没有对Blazor WASM项目进行任何更改,也没有进行重复代码的显著复制。
  • 唯一需要更改的是引用和launchSettings.json & appsettings.json
  • 至于Blazor Server-Side中的Startup配置,您只需在Blazor WASM项目中创建扩展方法,并在Blazor Server-Side项目中使用它们即可。

注意:我认为这仅适用于开发过程中调试,因为WASM Razor文件无法充分利用真正的Blazor Server-Side的功能,因为它仍将使用HTTP请求。

Blazor WASM Project running as Blazor Server-Side


希望下面有反馈!:DD


在这种情况下,如何处理身份验证? - Mihaimyh
谢谢!这个很好用,绝对让开发体验更加愉悦。标准的WASM启动/调试体验非常耗时,基本上无法使用,但是我只是使用了Core i7,希望微软能尽快修复它。 - Gordon Rudman
@Gordon Rudman 确实。虽然 .NET 5 发布已经临近,希望在开发体验方面有所改进,但与此同时我们可以这样做。 - DaaWaan
@Mihaimyh 很抱歉回复晚了,我不认为将 Blazor WASM 作为 Blazor 服务器端运行会影响身份验证。如果我漏掉了什么,请指教。 - DaaWaan
优美的答案......同样适用于 .NET 6.0。 - Rohit Kumar
当我们在 Blazor WebAssembly 上基于 JWT 进行身份验证和授权时,并不是太容易。不幸的是,当令牌在 WebAssembly 上使用时,在服务器端授权无法正常工作。 - mRizvandi

3
我建议另一种方式。从服务器项目引用WASM项目还存在其他缺点,但个人认为这是一个架构上不优雅的解决方案。
Blazor Server和WASM在以下关键领域存在差异:
1.身份验证:Blazor Server允许您在运行时自定义对特定区域的访问。在WASM中,授权一次性完成,并将应用程序代码完全发送。
2.数据库访问:Blazor Server允许直接访问EF Core实体(因为代码仅在服务器上执行)。在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相关的开销外,不需要进行额外的编码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接