其實這篇文章算是遲到了很長時間了,不過現(xiàn)在寫出來還不算太晚。.NET Core 3.0已經(jīng)出來一段時間了,隨.NET Core 3.0出來的,還有一個名為Blazor的框架。今天我試用了一下,感覺很有意思。這個框架的潛力很大,而且因為基于.NET技術,對于C#程序員來說學習門檻很低,開發(fā)效率高的一筆。所以來給大家介紹一下。

官方介紹
首先來看看官方對于blazor框架的一些介紹:
Blazor 是一個使用 .NET 生成交互式客戶端 Web UI 的框架:
- 使用 C# 代替 JavaScript 來創(chuàng)建豐富的交互式 UI。
- 共享使用 .NET 編寫的服務器端和客戶端應用邏輯。
- 將 UI 呈現(xiàn)為 HTML 和 CSS,以支持眾多瀏覽器,其中包括移動瀏覽器。
使用 .NET 進行客戶端 Web 開發(fā)可提供以下優(yōu)勢:
- 使用 C# 代替 JavaScript 來編寫代碼。
- 利用現(xiàn)有的 .NET 庫生態(tài)系統(tǒng)。
- 在服務器和客戶端之間共享應用邏輯。
- 受益于 .NET 的性能、可靠性和安全性。
- 始終高效支持 Windows、Linux 和 macOS 上的 Visual Studio。
- 以一組穩(wěn)定、功能豐富且易用的通用語言、框架和工具為基礎來進行生成。
簡單來說,Blazor是一個開發(fā)客戶端網(wǎng)頁程序的框架。需要注意,根據(jù)官網(wǎng)的說明,如果你要開發(fā)網(wǎng)站類型的應用,還是應該用ASP.NET Core等框架。Blazor比較適合傳統(tǒng)企業(yè),在內(nèi)網(wǎng)中運行,用戶數(shù)量不多,基于瀏覽器的應用。
目前Blazor有兩個版本,Server版本利用HTML、CSS等網(wǎng)頁技術,項目運行的時候需要連接服務器。官網(wǎng)也就介紹了Server版的優(yōu)缺點。
Blazor 服務器托管模型具有以下幾個優(yōu)點:
- 下載大小明顯小于 Blazor WebAssembly 應用,且應用加載速度快得多。
- 應用充分利用服務器功能,包括使用任何與 .NET Core 兼容的 Api。
- 服務器上的 .NET Core 用于運行應用程序,因此現(xiàn)有的 .NET 工具(如調(diào)試)可按預期方式工作。
- 支持瘦客戶端。 例如,Blazor 服務器應用程序適用于不支持 WebAssembly 的瀏覽器以及資源受限設備上的瀏覽器。
- 應用程序的 .NET/C#代碼庫(包括應用程序的組件代碼)不會提供給客戶端。
Blazor 服務器托管有缺點:
- 通常存在較高的延遲。 每個用戶交互都涉及網(wǎng)絡躍點。
- 無脫機支持。 如果客戶端連接失敗,應用將停止工作。
- 對于包含多個用戶的應用而言,可伸縮性非常困難。 服務器必須管理多個客戶端連接并處理客戶端狀態(tài)。
- 為應用提供服務需要 ASP.NET Core 服務器。 不可能的無服務器部署方案(例如,通過 CDN 為應用提供服務)。
Blazor的另一個版本基于WebAssembly技術,可以支持離線運行,而且借由WebAssembly的計算高性能特性,可以在瀏覽器中運行的更高效。官網(wǎng)也介紹了其優(yōu)缺點。不過WebAssembly版目前還在測試當中,正式版將隨.NET Core 3.1一起推出。
Blazor WebAssembly 托管模型具有以下幾個優(yōu)點:
- 沒有 .NET 服務器端依賴項。 應用在下載到客戶端之后完全正常運行。
- 完全利用客戶端資源和功能。
- 工作從服務器卸載到客戶端。
-- 不需要 ASP.NET Core web 服務器來托管應用程序。 無服務器部署方案可能(例如,通過 CDN 提供應用)。-B- lazor WebAssembly 托管有缺點:-
- 應用程序限制為瀏覽器的功能。-
- 需要支持的客戶端硬件和軟件(例如,WebAssembly 支持)。
- 下載大小較大,應用需要較長時間才能加載。
- .NET 運行時和工具支持不太成熟。 例如, .NET Standard支持和調(diào)試中存在限制。
Blazor示例項目
好了,不多說廢話了,讓我們直接來看看Blazor項目是什么樣子的吧,這里以Blazor Server為例。它也是.NET Core項目,所以集成了.NET Core的所有好處,可以跨平臺,各種IDE和編輯器都支持。這里以Visual Studio為例來說明,當然你也可以使用Visual Studio Code等編輯器。
首先用VS創(chuàng)建一個Blazor項目,項目配置如圖所示。稍等片刻,項目就創(chuàng)建好了。

然后用調(diào)試功能,即可運行程序。程序運行結果如圖所示。

好了,讓我們來看看項目代碼吧。
首先來看看項目節(jié)奏,一個標準的ASP.NET Core 項目。wwwroot目錄存放項目用到的CSS、JS等文件;Data目錄存放數(shù)據(jù)庫相關的代碼;Pages目錄存放項目頁面對應的Razor模板代碼;Shared目錄存放項目頁面的公共模板。

主頁
主頁對應的代碼很簡單,如下所示。page指令指定了本頁面對應的URL。
@page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
計數(shù)器
第二個頁面的功能是計數(shù)器,功能很簡單,點擊頁面上的按鈕,計數(shù)器數(shù)字加一。

對應的代碼如下。需要注意的是這里onclick后面的不是通常意義的JS函數(shù),而是code指令里面的C#函數(shù)。相信對于C#程序員來說,這樣來編寫頁面確實更簡單方便。
@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
int currentCount = 0;
void IncrementCount()
{
currentCount++;
}
}
異步加載
最后一個功能很有意思,利用C#的異步功能實現(xiàn)了頁面異步加載數(shù)據(jù)的功能。當切換到這個頁面的時候,默認顯示加載中,當數(shù)據(jù)加載完畢的時候,切換顯示出數(shù)據(jù)表格。

這個頁面對應的功能如下??梢钥吹酵瓿僧惒焦δ艿拇a很簡單,就是一個C#異步方法。然后頁面里用if-else指令來切換數(shù)據(jù)顯示,當獲取到數(shù)據(jù)之后就顯示。
@page "/fetchdata"
@using BlazorApp1.Data
@inject WeatherForecastService ForecastService
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from a service.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}
}
那么這個ForecastService類是何方神圣呢?我們再來看看它的實現(xiàn)代碼。代碼實現(xiàn)實際上也很簡單,就是利用LINQ功能產(chǎn)生了一組隨機數(shù)據(jù)。
using System;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorApp1.Data
{
public class WeatherForecastService
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
{
var rng = new Random();
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = startDate.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
}).ToArray());
}
}
}
可以看到利用Blazor框架來實現(xiàn)頁面異步加載這個功能,對于.NET程序員來說很簡單。假如利用React、Vue等前端技術來實現(xiàn)的話,需要學習大量額外的知識。這也正是Blazor框架的目的所在,讓C#程序員更加方便的實現(xiàn)同樣的功能。
將來Blazor WebAssembly還會提供離線Web程序的功能,為.NET程序員們帶來更多功能。這些年來.NET Core開源的成果大家有目共睹,可以期待未來.NET編程領域出現(xiàn)更多優(yōu)質(zhì)框架,讓程序員們能享受到更美好的生活。