選單
GSS 技術部落格
在這個園地裡我們將從技術、專案管理、客戶對談面和大家分享我們多年的經驗,希望大家不管是喜歡或是有意見,都可以回饋給我們,讓我們有機會和大家對話並一起成長!
若有任何問題請來信:gss_crm@gss.com.tw
3 分鐘閱讀時間 (685 個字)

Blazor WebAssembly 與 Server 相互轉換

ae48eb5e5f307da3698441e86f641ccc4048d77b_2_1024x919

前言

開發 ASP.NET Core Blazor 時,可以選擇使用 Blazor WebAssembly (client-side) 或是 Blazor Server (server-side)的方式。
但是當選擇好了後,可以改成別的嗎?
例如 Blazor WebAssembly 改成 Blazor Server 或是 Blazor Server 改成 Blazor WebAssembly 嗎?

研究

在轉換前,先建立 Blazor WebAssembly 及 Blazor Server 來比較一下,如下,

我們可以發現,那些 Razor Page 大多可以在 WebAssembly or Server 上執行,
而 Server 專案中 Pages 目錄的 _Host.cshtml ,則可以對應到 WebAssembly 專案中 wwwroot 裡的 index.html,如下,

另外就是 Blazor WebAssembly 沒有 Startup.cs ,所以 Services 的 DI 設定,是寫在 Program.cs 之中。
所以,不管原本是 Blazor WebAssembly 或是 Blazor Server ,我們都可以將目前這個專案變成是給 Blazor WebAssembly 或是 Blazor Server 參考使用的共用專案。

實作

了解這些差異後,Blazor WebAssembly 與 Server 就相互轉換。

新增專案

例如我原本是使用 Blazor WebAssembly (remeberPws),所以如果我要改用 Blazor Server 的話,就新增 Blazor Server 專案 (remeberPwds.Server)。
再將不需要的 Razor 檔案刪除,如下,


只剩下 _Host.cshtml 、 Programs.cs 及 Starup.cs

修改原有專案成為 LIBRARY

remeberPws 專案原本是 Web 專案,所以要改成 Razor 專案才可以給其他專案共用,所以,原本的內容如下,

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    <RazorLangVersion>3.0</RazorLangVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.1" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.1" PrivateAssets="all" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.1" PrivateAssets="all" />
    <PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\remeberPwds.Shared\remeberPwds.Shared.csproj" />
  </ItemGroup>
</Project>

  • 將 Sdk 從 Microsoft.NET.Sdk.Web 改成 Microsoft.NET.Sdk.Razor
  • PackageReference 中的參考原本是 WebAssembly ,要改成 Microsoft.AspNetCore.Components
    所以調整後如下,
<Project Sdk="Microsoft.NET.Sdk.Razor">
  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    <RazorLangVersion>3.0</RazorLangVersion>
  </PropertyGroup>
  <ItemGroup>
	  <PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.4" />
	  <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.4" />
	  <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.4" />
	  <PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="..\remeberPwds.Shared\remeberPwds.Shared.csproj" />
  </ItemGroup>
</Project>

  • 將 _Imports.razor 中的 @using Microsoft.AspNetCore.Components.WebAssembly.Http 移除
  • 將 App.razor 檔案 AppAssembly 的 typeof 從 Program 改成 App

改完後,可以發現原有的專案已從 Web 專案變成了 Razor Library 專案,可以給別的專案參考使用

  • Blazor Server 專案(remeberPwds.Server),將原有的專案(remeberPws)加入參考
  • 將 Program.cs 中設定 Service DI 的部份,搬到 Blazor Server 專案中的 Startup.cs 之中。註: 這裡有個需要注意的是 Blazor WebAssembly 的 Service.AddScoped 與 AddSingleton 效果是一樣的。 而 Blazor Server 的 AddScoped 是為 SignalR Connection 為主
  • Blazor Server 專案中的 _Host.cshtml CSS 要改參考到 原有的專案(remeberPws)裡面 , component type 也要改用 原專案的 App。css 可以直接從(remeberPws)的wwwroot那直接拉進來。

建置沒有錯誤後,請將啟始專案改為 Blazor Server 專案(remeberPwds.Server)

調整後的方案如下,


Blazor Server 專案(remeberPwds.Server) 可以正常運作,

所以如果原本是 Blazor Server 專案 要這樣轉成 Blazor WebAssembly 也是可以的哦!
只是需要注意的是,如果在 Blazor Server 中使用 EF Core ,則需要將它抽到 API 專案之中,
所以在方案的規劃中可以是 Blazor (Client or Server)專案 + Blazor App 專案 + Blazor Component 專案 + Shared Model 專案 + API 專案。


參考資料

Blazor
Blazor University

有效地使用 ASP.NET Core Logging - 1
The frame attempting navigation is sandboxed, and ...