用C#代替Javascript来做Web应用,是有多爽?

今天聊聊 Blazor。

Blazor 是一个 Web UI 框架。这个框架允许开发者使用 C# 来创建可运行于浏览器的具有完全交互 UI 的 Web 应用。

可以理解为,这是一个 C# 语言的 Vue / Angular / React,可以和 HTML、CSS 一起实现可重用的 Web UI,可以和服务器共享代码和库。

Blazor 拥有现代 Web 框架具备的所有功能,包括:

  • 用于构建 composable UI 的组件模型

  • 路由

  • 布局

  • 表格和验证

  • 依赖注入

  • JavaScript 互操作

  • 开发期间在浏览器中实时重新加载

  • 服务器端渲染

  • 在浏览器和 IDE 中全面调试 .NET

  • 能够通过 asm.js 在较早版本的(非 WebAssembly )浏览器上运行

Blazor 有两种托管模型:

  • Blazor WebAssembly (blazorwasm)
  • Blazor Server (blazorserver)

两种模型从应用层面没有太大的区别,但从实际运行和布署上,两个模型还是有相当的区别的。

Blazor WebAssembly 应用跑在浏览器上,要求浏览器支持 WebAssembly。换句话说,早期的一些浏览器并不支持 WebAssembly,所以也无法使用。同时,应用在首次运行时,需要下载应用和应用依赖项和运行时到本地,所以会有个加载延时。但是,这种模型可以全部运行在客户端,充分利用客户端资源,对服务器压力小。

Blazor Server 则相反,应用跑在服务器上,通过SignalR来处理 UI 更新、事件处理。所以,它加载速度快,可以充分利用服务器功能,并可以运行早期的浏览器。不过,因为应用需要跟服务器通讯,所以,不支持脱机工作,服务器压力大。

简单的区别就这么多,详细的内容,我会另开一文来说。

今天我们主说 Blazor for Server-Side ,也就是上面介绍的 Blazor Server 模型。

    为了防止不提供原网址的转载,特在这里加上原文链接:https://www.cnblogs.com/tiger-wang/p/13264415.html

一、创建空项目

我们先创建一个Web空项目:

% dotnet new sln -o demo
The template "Solution File" was created successfully.
% cd demo 
% dotnet new web -o demo
The template "ASP.NET Core Empty" was created successfully. Processing post-creation actions...
Running 'dotnet restore' on demo/demo.csproj...
  Determining projects to restore...
  Restored /demo/demo/demo.csproj (in 148 ms). Restore succeeded.
% dotnet sln add demo/demo.csproj 
Project `demo/demo.csproj` added to the solution.

创建完成。看一下目录结构:

% tree .
.
├── demo
│   ├── Program.cs
│   ├── Properties
│   │   └── launchSettings.json
│   ├── Startup.cs
│   ├── appsettings.Development.json
│   ├── appsettings.json
│   └── demo.csproj
└── demo.sln

这就是我们的基础项目了。后面所有的项目,都会在这个基础上进行修改和增加。

二、添加 Blazor 服务

打开Startup.cs文件。

1. 修改 ConfigureServices

ConfigureServices中添加:

services.AddRazorPages();
services.AddServerSideBlazor();

这两行代码中,services.AddRazorPages()是添加Razor服务。

RazorBlazor名字很像,但本身并没有关系。Razor是一种服务器标记语言,类似于PHP

这里添加Razor,只是因为我习惯用Razor,并没有特殊性。如果你习惯用 MVC,这儿也可以换成services.AddMvc(),是一样的。

下面一行services.AddServerSideBlazor(),才是真正的内容:添加Blazor Server-Side服务。

2. 修改 Configure

Configure中添加:

app.UseStaticFiles();
app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub();
});

其中,app.UseStaticFiles()表明我们会用到静态文件。文件默认要求放在wwwroot目录下,所以可以把目录也建了。

app.UseEndpoints,需要使用Blazor路由,所以要改成endpoints.MapBlazorHub()

这儿就完成了。

3. 加入路由

接下来,我们需要建立路由。在项目中建一个目录Pages。这是Blazor默认的单页面目录。然后在里面建一个_Host.cshtml

@page "/"
@namespace demo.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Demo</title>
    <base href="~/" />
</head>
<body>
    <app>
        <component type="typeof(App)" render-mode="ServerPrerendered" />
    </app>
    <script src="_framework/blazor.server.js"></script>
</body>
</html>

然后在Startup.cs文件的Configure中加入回退路由:

app.UseEndpoints(endpoints =>
{
    endpoints.MapBlazorHub();
    endpoints.MapFallbackToPage("/_Host");
});

这里把这个_Host.cshtml登记为回退路由,作用是把所有请求到 Razor 的页面,先路由到这个页面中,由这个页面做最终合成。

这个页面中必须有的元素为:

  • @page,定义这个页面的访问点
  • @namespace,当前页面的namespace
  • addTagHelper,标记帮助
  • base,定义这个页面的路由起始
  • app,这一句是这个页面的核心。我们后边创建的Razor页面,会以一个组件的形式,放在这个位置
  • script,用来跟服务器通讯

上面的代码中,调用到一个typeof(App),这个App,是路由组件。下面我们来创建这个路由 - 创建一个App.razor

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" />
    </Found>
    <NotFound>
        Page Not found
    </NotFound>
</Router>

这个模板的用处,是在 Dotnet 编译时.razor时,为带有@page的类提供指定的路由模板属性RouteAttribute,同时,也映射出了上面说的App类。

运行。浏览器中会出现Page Not Found。这是我们在App.razor里定义的,表明我们没有找到任何可用的路由。

三、创建一个页面

下面,我们来创建一个页面index.razor

@page "/"

<h1>Hello, world!</h1>

这个页面简单。

@page,告诉路由这个页面的URL是/

再运行,我们就看到了这个页面。

@page定义的是这个页面的路由。路由有以下几种样式,我简单列一下:

  • 直接路由:/page
  • 参数路由:/page/{page_id}
  • 约束路由:/page/{page_id: int}

四、创建一个布局模板

我们先在项目中创建一个目录Shared,用来存放各种组件和模板。在目录中,我们创建一个布局模板 - MainLayout.razor

@using Microsoft.AspNetCore.Components
@inherits LayoutComponentBase <div>
    <h3>This is layout</h3>
</div>
@Body

这里面有几个重点:

  • 布局模板必须继承自类LayoutComponentBase
  • @Body定义了引用布局的页面的内容位置
  • Body的数据类型是RenderFragment,在Microsoft.AspNetCore.Components中,需要引用

其实这些操作,都是C#的结构,只不过用了Razor,换了一种写法

下面,我们给刚才的Index.razor加入布局模板:

@using demo.Shared
@layout MainLayout

只要在Index.razor代码的最上边加上这两行就行。这两行中:

@layout是定义这个页面用哪个布局模板的;而@using是引用这个模板的位置,就是 C# 中的using

运行,我们就看到,这个布局加到页面前边了。

五、设置默认布局引用

上面的例子,是把布局给到一个页面。

我们也可以设置所有页面的默认布局模板,通过改动路由模板App.razor

@using demo.Shared

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        Page Not Found
    </NotFound>
</Router>

对方前边的文件内容,这一段,仅仅在RouteView中加了一个DefaultLayout

现在,所有的页面都默认加上了布局模板。

六、设置默认命名空间引用

上面的例子,在App.razorIndex.razor中,我们都引用了demo.Shared命名空间。

Blazor提供了一个默认的文件,叫_Imports.razor,用来存放所有.razor文件中共同的引用。

@using demo.Shared

我们把引用加到这个文件中,同时把上面两个.razor中的引用去掉,就完成了。

*这儿也多说一句:布局模板也可以在这里引用。布局模板的引用优先级是:页面引用 > _Imports.razor引用 > App.razor 引用。

以上就是Blazor Server的项目结构。做好这个结构后,所有的功夫,就只在 Razor 页面了。

(全文完)

本文的代码在https://github.com/humornif/Demo-Code/tree/master/0017/demo


微信公众号:老王Plus

扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送

本文版权归作者所有,转载请保留此声明和原文链接

一文说通Blazor for Server-Side的项目结构的更多相关文章

  1. 第三篇——第二部分——第二文 计划搭建SQL Server镜像

    原文:第三篇--第二部分--第二文 计划搭建SQL Server镜像 本文紧跟上一章:SQL Server镜像简介 本文出处:http://blog.csdn.net/dba_huangzj/arti ...

  2. 一文说通Dotnet Core的后台任务

    这是一文说通系列的第二篇,里面有些内容会用到第一篇中间件的部分概念.如果需要,可以参看第一篇:一文说通Dotnet Core的中间件   一.前言 后台任务在一些特殊的应用场合,有相当的需求. 比方, ...

  3. 一文说通C#中的异步编程补遗

    前文写了关于C#中的异步编程.后台有无数人在讨论,很多人把异步和多线程混了. 文章在这儿:一文说通C#中的异步编程 所以,本文从体系的角度,再写一下这个异步编程.   一.C#中的异步编程演变 1. ...

  4. Node.js 从零开发 web server博客项目[安全]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  5. 在Myeclipse buildpath 加server lib (server runtime)/项目导入时报错:The import javax.servlet.http.HttpServletRequest cannot be resolved

    来源于:http://blog.csdn.net/dingqinghu/article/details/8805922 http://yl-fighting.iteye.com/blog/140946 ...

  6. eclipse新建web项目,发布 run as 方式和 new server然后添加项目方式。 后者无法自动编译java 成class文件到classes包下。

    eclipse新建web项目,发布 run as 方式和 new server然后添加项目方式. 后者无法自动编译java 成class文件到classes包下. 建议使用run as  -  run ...

  7. Node.js 从零开发 web server博客项目[express重构博客项目]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  8. Node.js 从零开发 web server博客项目[数据存储]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  9. Node.js 从零开发 web server博客项目[koa2重构博客项目]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

随机推荐

  1. 如何快速的找到好玩的旅游景点信息?Python爬虫帮你轻松解决

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 喜欢的朋友欢迎关注小编 当我们出去旅游时,会看这个地方有哪些旅游景点,景点 ...

  2. ubuntu12.04 串口登录系统配置

    原文转自:http://blog.csdn.net/g__gle/article/details/8663239 1) Create a file called /etc/init/ttyS0.con ...

  3. 小师妹学JavaIO之:NIO中那些奇怪的Buffer

    目录 简介 Buffer的分类 Big Endian 和 Little Endian aligned内存对齐 总结 简介 妖魔鬼怪快快显形,今天F师兄帮助小师妹来斩妖除魔啦,什么BufferB,Buf ...

  4. iOS-键盘弹出或隐藏时调整输入框的位置

    要达到自动调整的目标需要监听 keyboardWillShowNotification 跟 keyboardWillHideNotification, 同时需要实现点击其它地方时,通知隐藏键盘的事件 ...

  5. DML_Data Modification_UPDATE

    DML_Data Modification_UPDATE写不进去,不能专注了...... /* */ ------------------------------------------------- ...

  6. 2019-02-02 Python学习之死锁和Rlock

    死锁:"当一个线程永远地持有一个锁,并且其他线程都尝试去获得这个锁时,那么它们将永远被阻塞" e.g. import threading import time mutexboy ...

  7. 容器技术之Docker资源限制

    上一篇我们聊到了docker容器的单机编排工具docker-compose的简单使用,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13121678.html: ...

  8. 一行代码让你的python运行速度提高100倍

    转自:https://www.cnblogs.com/xihuineng/p/10630116.html 加上之后运行速度快了十倍,我的天呐. python一直被病垢运行速度太慢,但是实际上pytho ...

  9. LaTeX中常用代码段snippets(持续更新)

    1.displaymath 单行数学环境,不带编号. \begin{displaymath} This\ is\ displaymath\ envirment.\ I\ don 't\ have\ a ...

  10. PN532模块连接-读卡失败原因

    第一步:点击发现NFC设备 第二步:点击读整卡:读取卡片内容. 若不成功,把UID卡移开,再放一次.再点第一步,显示发现NFC,再点第二步.反复操作,直到读取到为止.2-3次一般都会成功 . 相关软件 ...