Asp Net Core学习笔记:(四)Blazor WebAssembly入门

本来今天开始是有其他的安排了,也没办法抽出那么多时间来学NetCore,不过我想做事情有始有终吧,除了gRPC还没跑起来之外,Blazor这部分也了解了一点,官网地址:https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor

目前来说还不是很完善,真正的离线单页应用还处于预览版阶段。

Blazor目前有两种运行模式,一种是服务器端部署,一种是客户端部署,后者可以完全脱离服务器,也就是标题写的WebAssembly,不过目前处于预览版(有点标题党了)。

官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/blazor/get-started?view=aspnetcore-3.1&tabs=visual-studio

项目文件结构

主要的文件夹就是这个Pages和Shared。里面包含了mvc页面(cshtml结尾)和razor组件(razor结尾)。

然后再看看wwwroot文件夹:

可以看到只有css,没有js文件夹,因为blazor要做的事情就是要把js代码换成C#代码,其实就是让后端开发去做前端开发。 (PS:node就是让前端去做后端,历史总是惊人的相似hhh)

先看看它的代码是怎么写的,后面再具体介绍。

例子代码

这是官方的例子,点击按钮之后可以计算点击次数。

@page "/counter"
<h1>Counter</h1>
<p>Current count: @_currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
    private int _currentCount = 0;
    private void IncrementCount()
    {
        _currentCount++;
    }
}

我感觉项目的具体代码应该放在最后面,还是继续介绍一下原理什么的吧~

托管模型

就是前文提到的服务器和客户端两种模式。

客户端模型

Blazor 的主体宿主模型在 WebAssembly 上的浏览器中运行客户端。 将 Blazor 应用、其依赖项以及 .NET 运行时下载到浏览器。 应用将在浏览器线程中直接执行。 UI 更新和事件处理发生在同一进程中。 应用的资产将作为静态文件部署到 web 服务器或可为客户端提供静态内容的服务。

服务端模型

使用 Blazor 服务器托管模型,可在服务器上从 ASP.NET Core 应用中执行应用。 UI 更新、事件处理和 JavaScript 调用是通过 SignalR 连接进行处理。

又出现SignalR了,真的好用,关于SignalR的可以看看我上一篇:Asp.Net Core学习笔记:(三)使用SignalR实时通信框架开发聊天室

Blazor Server 宿主模型具有以下几个优点: - 下载大小明显小于 Blazor WebAssembly 应用,且应用加载速度快得多。 - 应用充分利用服务器功能,包括使用任何与 .NET Core 兼容的 Api。 - 服务器上的 .NET Core 用于运行应用程序,因此现有的 .NET 工具(如调试)可按预期方式工作。 - 支持瘦客户端。 例如,Blazor Server apps 适用于不支持 WebAssembly 的浏览器以及资源受限设备上的浏览器。 - 应用程序的 .NET/C#代码库(包括应用程序的组件代码)不会提供给客户端。

Blazor Server 宿主有一些缺点: - 通常存在较高的延迟。 每个用户交互都涉及网络跃点。 - 无脱机支持。 如果客户端连接失败,应用将停止工作。 - 对于包含多个用户的应用而言,可伸缩性非常困难。 服务器必须管理多个客户端连接并处理客户端状态。 - 为应用提供服务需要 ASP.NET Core 服务器。 不可能的无服务器部署方案(例如,通过 CDN 为应用提供服务)。

项目配置

首先是从一个普通的AspNetCore项目开始,进行以下配置:

// 注册服务
public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<WeatherForecastService>();
}

// 配置中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        // 配置生产环境的错误页面
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        // 相当于一个Blazor版的SignalR
        endpoints.MapBlazorHub();
        endpoints.MapFallbackToPage("/_Host");
    });
}

编写Razor组件

Blazor从名字看就和AspNetCore原有的Razor相似,所以他们俩的很多语法是接近的,比如说TagHelper。

先写App.razor

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Sorry, there's nothing at this address.</p>
        </LayoutView>
    </NotFound>
</Router>

之前在中间件那里配置了endpoints.MapFallbackToPage("/_Host");,可以理解为默认页面吧。

内容如下:

@page "/"
@namespace BlazorOne.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = null;
}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BlazorOne</title>
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
</head>
<body>
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>

    <script src="_framework/blazor.server.js"></script>
</body>
</html>

可以看到就是一个普通的AspNetCore的MVC页面的写法,不过body里面有app节点,可以渲染其他Razor组件。

效果

这是官方例子跑起来的效果,我也没想出来拿这个做什么好,所以就单纯跑一下官方例子好了(懒)

我发现微软的官方文档还是不错的,虽然好像有点像是机翻的,但是看起来还挺通顺,也很详细。

官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/blazor/hosting-models?view=aspnetcore-3.1

欢迎交流

交流问题请在微信公众号后台留言,每一条信息我都会回复哈~ - 微信公众号:画星星高手 - 打代码直播间:https://live.bilibili.com/11883038 - 知乎:https://www.zhihu.com/people/dealiaxy - 专栏:https://zhuanlan.zhihu.com/deali - 简书:https://www.jianshu.com/u/965b95853b9f