.NET開發(fā)人員的Blazor的入門指南(.net core blazor)
Blazor為數百萬.NET開發(fā)人員帶來了WebAssembly的世界,允許他們編寫在瀏覽器上運行的C#。
多年來,如果您想編寫代碼以在瀏覽器中運行,您的選擇是JavaScript或JavaScript。對于某些瀏覽器上的幾個短暫時期,您可以使用其他語言,但它們并不重要:IE上的VBScript和特殊版Chrome上的Dart。
還有一些語言可以編譯成JavaScript(TypeScript,CoffeeScript,…),但它們仍然是真正的JavaScript。JavaScript單一文化的日子隨著WebAssembly(Wasm)的出現而出現。對于.NET開發(fā)人員,Wasm以Blazor的形式到達。
什么是WebAssembly?
WebAssembly是瀏覽器中支持運行Wasm字節(jié)碼的虛擬機規(guī)范。這種二進制格式允許比典型的JavaScript更快的執(zhí)行,因此性能可以比純JavaScript更好。有許多編譯器可以輸出這種格式,包括LLVM。因此,現在可以用C 編寫代碼,將其編譯為Wasm程序集,將其發(fā)送到瀏覽器,然后直接運行。
瀏覽器對Wasm的支持非常廣泛。即使在較舊的瀏覽器上,也可以通過asm.js獲得支持,盡管性能閾值較低。
.NET如何支持Wasm
許多語言已經開始通過輸出Wasm程序集將其語言帶到WebAssembly的項目。微軟采用的方法與大多數其他平臺略有不同。通常,您會將輸出二進制文件編譯為Wasm,然后直接在瀏覽器中加載它們。但是,.NET二進制文件已經采用通用語言設計,可以在.NET Framework上運行:中間語言。因此,如果不是將代碼編譯為Wasm,而是將框架本身編譯為Web Assembly,他們可以解釋他們已經使用這個框架的Wasm版本的相同二進制文件。
當然,.NET Standard統(tǒng)一了.NET Framework的幾種不同風格。作為WebAssembly運行的版本實際上是Mono。有人擔心使用Mono而不是.NET Core,我可以理解。使用多個.NET框架有點煩人,但各種框架之間的標準化工作非常好。
什么是Blazor?
我想告訴人們Blazor并將整個.NET Framework編譯為Wasm是完全瘋狂的。事實上Blazor是Steve Sanderson的一個項目,他之前曾創(chuàng)建過一些偉大的瘋狂項目:xVal,Knockout,JavaScript服務。因此,隨著瘋狂項目的進行,我們掌握得非常好。
Blazor是一個高度實驗性的項目,它將ASP.NET的感覺帶給了Wasm。您使用您識別并記住的所有工具在C#中編寫代碼。您仍然可以使用過去的相同工具進行單元測試。您仍然可以使用相同的日志記錄工具。實際上,您可以掌握所有C#知識并編寫Web應用程序。
服務器端VS. 客戶端
目前Blazor有兩種型號:客戶端和服務器端型號??蛻舳税姹緦嶋H上通過Wasm在瀏覽器中運行,并且在那里完成對DOM的更新,而服務器端模型在服務器上保留DOM的模型并使用以下方式在瀏覽器和服務器之間來回傳輸差異。 SignalR管道。事實上,服務器端更有可能成為一個真正的產品,并且已經承諾用于ASP.NET Core 3,這聽起來好像是一年之后。
這真的可以表現嗎?
有許多因素使得以這種方式部署的應用程序的性能看起來很糟糕。第一個是.NET Framework的大尺寸。將.NET框架的加載捆綁到每個網站加載中是很大的。但是,已有技術可以使其更易于管理。如果框架是從CDN傳遞的,瀏覽器可以緩存框架,甚至可以在站點之間重用它。稍微更奇特的方法是使用樹搖動來移除應用程序未使用的框架的巨大條帶。
該項目中最大的資產是mono.wasm文件,即869KB。項目中使用的各種DLL總計幾乎達到一兆字節(jié)。
這是很多下載的框架代碼,幾乎沒有任何實際功能的2MB,所以這確實是一個問題。
接下來,.NET代碼可以在傳送到瀏覽器時以高效的方式運行并編譯成奇怪的匯編語言嗎?目前,編譯為Wasm的C項目似乎有50%的減速。顯然,在瀏覽器中運行框架會有一些開銷,但我們還不確定它將在何處著陸。正在努力改進和優(yōu)化速度,并且當它達到生產性能時可能是合理的。很多這種表現只是因為Wasm通常比JavaScript更有效,盡管這樣的基準測試非常困難。
最終結果是,Wasm似乎比典型的JavaScript Web應用程序具有更大的啟動成本,但是一旦您啟動并運行任何類型的計算復雜操作都會更快。
Blazor項目入門
第一步是確保您在Visual Studio和.NET Core方面擁有的所有內容都是最新的。在撰寫本文時,我使用的是.NET Core工具版本2.1.500。接下來,有一些工具可以讓Blazor更加愉快。第一個是可以通過運行安裝的模板集合:
dotnet new -i Microsoft.AspNetCore.Blazor.Templates
從命令行。我們將在本文中使用完整的Visual Studio,但您可以使用VS Code或vi或任何您想要的。在Visual Studio中,安裝Blazor擴展,官方Blazor文檔建議運行至少VS 15.9,但我運行15.8沒有問題。
有了所有這些,我們就可以開始一個全新的Blazor項目。在新項目對話框中,選擇一個新的ASP.NET Core項目。在模板選擇對話框中,有三個基于Blazor的模板:
- Blazor – 完整的客戶端Blazor應用程序,沒有任何服務器端組件。這適用于部署到S3或Azure Blob存儲等靜態(tài)主機。
- Blazor(ASP.NET Core托管) – 一個客戶端應用程序,其服務器端為Blazor提供服務,并且還提供放置服務器端API的位置。
- Blazor(ASP.NET核心中的服務器端) – 服務器端應用程序,通過SignalR從服務器更新DOM
出于我們的目的,我們將使用ASP.NET Core托管變體。請記住,這個將DLL發(fā)送到瀏覽器的版本不會出現在ASP.NET Core 3的官方支持中,至少目前還沒有。
探索守則
從該模板創(chuàng)建的解決方案有三個項目。
- 客戶端包含在瀏覽器上運行的代碼。
- 服務器是服務器端代碼。默認項目有一個簡單的控制器,可以返回有關天氣的一些數據。
- 共享包含在客戶端和服務器端使用的代碼。像模特這樣的東西是一件很棒的事情。驗證元數據在這里也可能是一個很好的補充,因為它意味著你可以應用相同的驗證邏輯客戶端和服務器端。
最有趣的代碼是在Client項目中,因為Server項目主要只是一個標準的ASP.NET Core應用程序。您將注意到客戶端結構中的第一件事是它與ASP.NET Core項目的結構非常相似。
有一個Program.cs作為引導程序,就像你在ASP.NET Core應用程序中看到的那樣。Startup.cs包含設置服務和配置應用程序的代碼。這種相似性允許您將更多的ASP.NET核心知識帶到Blazor世界。HTML文件也都具有您熟悉和喜愛的相同.cshtml擴展名。打開其中一個文件可以發(fā)現它們使用的是與MVC相同的Razor語法,直到2008年。
最有趣的cshtml文件是FetchData.cshtml。
我們可以從FetchData.cshtml學到什么
@using Blazor2.Shared
@page “/fetchdata”
@inject HttpClient Http
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</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>
}
@functions {
WeatherForecast[] forecasts;
protected override async Task OnInitAsync()
{
forecasts = await Http.GetJsonAsync<WeatherForecast[]>(“api/SampleData/WeatherForecasts”);
}
}
在這個文件中,你會發(fā)現一些有趣的部分。@page指令用于提供路由器可用于將人們引導到頁面的位置。@inject允許注入服務。HttpClient是默認注冊的,不需要在Startup.cs中顯式輸入。這里有趣的是,這里使用的HttpClient與您在服務器端使用的HttpClient不同,因為在Wasm沙箱中不允許訪問原始套接字,就像在JavaScript中不允許這樣。最后,您會注意到有一個分支基于預測是否為空。Blazor實際監(jiān)視此屬性,當它更改時,將重新運行頁面呈現。變更檢測內置于。
擴展項目
為了將項目擴展到完全成熟的應用程序,您只需添加服務和cshtml頁面即可。只要您注意結構并匹配擴展ASP.NET Core應用程序的方式,您就應該保持良好的信譽。您可以通過NuGet添加對外部庫的引用,其中大部分都可以正常工作。但是,您應該記住,每次添加增加有效負載大小的包時,都需要將其發(fā)送到客戶端。由于基本軟件包的容量接近2MB,因此每下載的內容都要多得多。
限制
顯然,在瀏覽器中可以執(zhí)行的操作存在一些限制。在Wasm中運行的所有內容都在JavaScript沙箱中運行,這意味著您無法直接訪問磁盤或網絡等內容。因此,使用SQLClient直接與數據庫通信等許多功能都無法工作(無論如何這也是一個糟糕的想法)。庫可能包含嘗試寫入臨時文件的功能,這些功能無效。在計劃如何測試應用程序時,請記住這些限制。
點擊原生JavaScript代碼
Blazor和Wasm的一個非常好的部分是,它可以與JavaScript API進行交互。因此,如果您想通過地理定位API進行地理定位,您可以安裝Blazor.Geolocation(新近更新Blazor 0.7,BTW)等軟件包,它就可以正常工作。復雜的編組是為了映射JavaScript和.NET數據類型來回完成所有這些都是由Blazor完成的。在大多數情況下,您可以從.NET代碼輕松地從JavaScript和JavaScript方法調用.NET方法。心靈爆炸!
在Blazor.Geolocation示例中,要從瀏覽器的JavaScript上下文中獲取位置信息,您只需要在cshtml中注入位置服務并運行
location = await locationService.GetLocationAsync();
該軟件包負責處理從瀏覽器獲取位置信息的異步性質。其他JavaScript API可以類似地包裝。
您可以在Blazor文檔中詳細了解如何與JavaScript 交互。
出現問題時調試Blazor
調試故事目前并不出色。使用服務器端Blazor,在Visual Studio中一切都是F5可調試的,但是一旦你轉到客戶端,調試故事就沒有完全充實。Chrome中的“來源”選項卡包含一個令人困惑的文件陣列和Wasm函數,此時無法輕松調試。最終,可能會為所有這些提供源映射支持,并且體驗應該更好。但是,目前,編譯器無法輸出映射。
網絡流量可以像調整任何其他網絡流量一樣進行調試,例如在前綴中。同樣,服務器端仍然是標準的ASP.NET核心應用程序,因此它可以從Retrace或Prefix的檢測中受益。在這方面,至少調試和分析的故事非常好。
WebAssembly在哪里?
只有傻瓜才會對未來作出陳述,所以我在這里:我認為WebAssembly有一個光明的未來。為無數語言和編程范例解鎖Web開發(fā)將產生一些非常有趣的新框架。WebAssembly的速度也適用于從游戲到AI的各種代碼。