.NET开发人员的Blazor的入门指南(.net core blazor)
Blazor为数百万.NET开发人员带来了WebAssembly的世界,允许他们编写在浏览器上运行的C#。
多年来,如果您想编写代码以在浏览器中运行,您的选择是JavaScript或JavaScript。对于某些浏览器上的几个短暂时期,您可以使用其他语言,但它们并不重要:IE上的VBScript和特殊版Chrome上的Dart。
还有一些语言可以编译成JavaScript(TypeScript,CoffeeScript,…),但它们仍然是真正的JavaScript。JavaScript单一文化的日子随着WebAssembly(Wasm)的出现而出现。对于.NET开发人员,Wasm以Blazor的形式到达。
什么是WebAssembly?
WebAssembly是浏览器中支持运行Wasm字节码的虚拟机规范。这种二进制格式允许比典型的JavaScript更快的执行,因此性能可以比纯JavaScript更好。有许多编译器可以输出这种格式,包括LLVM。因此,现在可以用C 编写代码,将其编译为Wasm程序集,将其发送到浏览器,然后直接运行。
浏览器对Wasm的支持非常广泛。即使在较旧的浏览器上,也可以通过asm.js获得支持,尽管性能阈值较低。
.NET如何支持Wasm
许多语言已经开始通过输出Wasm程序集将其语言带到WebAssembly的项目。微软采用的方法与大多数其他平台略有不同。通常,您会将输出二进制文件编译为Wasm,然后直接在浏览器中加载它们。但是,.NET二进制文件已经采用通用语言设计,可以在.NET Framework上运行:中间语言。因此,如果不是将代码编译为Wasm,而是将框架本身编译为Web Assembly,他们可以解释他们已经使用这个框架的Wasm版本的相同二进制文件。
当然,.NET Standard统一了.NET Framework的几种不同风格。作为WebAssembly运行的版本实际上是Mono。有人担心使用Mono而不是.NET Core,我可以理解。使用多个.NET框架有点烦人,但各种框架之间的标准化工作非常好。
什么是Blazor?
我想告诉人们Blazor并将整个.NET Framework编译为Wasm是完全疯狂的。事实上Blazor是Steve Sanderson的一个项目,他之前曾创建过一些伟大的疯狂项目:xVal,Knockout,JavaScript服务。因此,随着疯狂项目的进行,我们掌握得非常好。
Blazor是一个高度实验性的项目,它将ASP.NET的感觉带给了Wasm。您使用您识别并记住的所有工具在C#中编写代码。您仍然可以使用过去的相同工具进行单元测试。您仍然可以使用相同的日志记录工具。实际上,您可以掌握所有C#知识并编写Web应用程序。
服务器端VS. 客户端
目前Blazor有两种型号:客户端和服务器端型号。客户端版本实际上通过Wasm在浏览器中运行,并且在那里完成对DOM的更新,而服务器端模型在服务器上保留DOM的模型并使用以下方式在浏览器和服务器之间来回传输差异。 SignalR管道。事实上,服务器端更有可能成为一个真正的产品,并且已经承诺用于ASP.NET Core 3,这听起来好像是一年之后。
这真的可以表现吗?
有许多因素使得以这种方式部署的应用程序的性能看起来很糟糕。第一个是.NET Framework的大尺寸。将.NET框架的加载捆绑到每个网站加载中是很大的。但是,已有技术可以使其更易于管理。如果框架是从CDN传递的,浏览器可以缓存框架,甚至可以在站点之间重用它。稍微更奇特的方法是使用树摇动来移除应用程序未使用的框架的巨大条带。
该项目中最大的资产是mono.wasm文件,即869KB。项目中使用的各种DLL总计几乎达到一兆字节。
这是很多下载的框架代码,几乎没有任何实际功能的2MB,所以这确实是一个问题。
接下来,.NET代码可以在传送到浏览器时以高效的方式运行并编译成奇怪的汇编语言吗?目前,编译为Wasm的C项目似乎有50%的减速。显然,在浏览器中运行框架会有一些开销,但我们还不确定它将在何处着陆。正在努力改进和优化速度,并且当它达到生产性能时可能是合理的。很多这种表现只是因为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存储等静态主机。
- Blazor(ASP.NET Core托管) – 一个客户端应用程序,其服务器端为Blazor提供服务,并且还提供放置服务器端API的位置。
- Blazor(ASP.NET核心中的服务器端) – 服务器端应用程序,通过SignalR从服务器更新DOM
出于我们的目的,我们将使用ASP.NET Core托管变体。请记住,这个将DLL发送到浏览器的版本不会出现在ASP.NET Core 3的官方支持中,至少目前还没有。
探索守则
从该模板创建的解决方案有三个项目。
- 客户端包含在浏览器上运行的代码。
- 服务器是服务器端代码。默认项目有一个简单的控制器,可以返回有关天气的一些数据。
- 共享包含在客户端和服务器端使用的代码。像模特这样的东西是一件很棒的事情。验证元数据在这里也可能是一个很好的补充,因为它意味着你可以应用相同的验证逻辑客户端和服务器端。
最有趣的代码是在Client项目中,因为Server项目主要只是一个标准的ASP.NET Core应用程序。您将注意到客户端结构中的第一件事是它与ASP.NET Core项目的结构非常相似。
有一个Program.cs作为引导程序,就像你在ASP.NET Core应用程序中看到的那样。Startup.cs包含设置服务和配置应用程序的代码。这种相似性允许您将更多的ASP.NET核心知识带到Blazor世界。HTML文件也都具有您熟悉和喜爱的相同.cshtml扩展名。打开其中一个文件可以发现它们使用的是与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”);
}
}
在这个文件中,你会发现一些有趣的部分。@page指令用于提供路由器可用于将人们引导到页面的位置。@inject允许注入服务。HttpClient是默认注册的,不需要在Startup.cs中显式输入。这里有趣的是,这里使用的HttpClient与您在服务器端使用的HttpClient不同,因为在Wasm沙箱中不允许访问原始套接字,就像在JavaScript中不允许这样。最后,您会注意到有一个分支基于预测是否为空。Blazor实际监视此属性,当它更改时,将重新运行页面呈现。变更检测内置于。
扩展项目
为了将项目扩展到完全成熟的应用程序,您只需添加服务和cshtml页面即可。只要您注意结构并匹配扩展ASP.NET Core应用程序的方式,您就应该保持良好的信誉。您可以通过NuGet添加对外部库的引用,其中大部分都可以正常工作。但是,您应该记住,每次添加增加有效负载大小的包时,都需要将其发送到客户端。由于基本软件包的容量接近2MB,因此每下载的内容都要多得多。
限制
显然,在浏览器中可以执行的操作存在一些限制。在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开发将产生一些非常有趣的新框架。WebAssembly的速度也适用于从游戏到AI的各种代码。