用C#代替Javascript来做Web应用,是有多爽?
?
今天聊聊 Blazor。
Blazor 是一个 Web UI 框架。这个框架允许开发者使用 C# 来创建可运行于浏览器的具有完全交互 UI 的 Web 应用。
可以理解为,这是一个 C# 语言的 Vue / Angular / React,可以和 HTML、CSS 一起实现可重用的 Web UI,可以和服务器共享代码和库。
Blazor 拥有现代 Web 框架具备的所有功能,包括:
?
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 文件。
在ConfigureServices 中添加:
services.AddRazorPages(); services.AddServerSideBlazor();
这两行代码中,services.AddRazorPages() 是添加Razor 服务。
Razor 和Blazor 名字很像,但本身并没有关系。Razor 是一种服务器标记语言,类似于PHP 。
这里添加Razor ,只是因为我习惯用Razor ,并没有特殊性。如果你习惯用 MVC,这儿也可以换成services.AddMvc() ,是一样的。
下面一行services.AddServerSideBlazor() ,才是真正的内容:添加Blazor Server-Side 服务。
在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"?/> ????<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 。
?
运行,我们就看到,这个布局加到页面前边了。
五、设置默认布局引用
上面的例子,是把布局给到一个页面。
我们也可以设置所有页面的默认布局模板,通过改动路由模板@using?demo.Shared
<"@routeData"?DefaultLayout="@typeof(MainLayout)"?/> ????</NotFound> ????????Page?Not?Found ????</Router>
对方前边的文件内容,这一段,仅仅在RouteView 中加了一个DefaultLayout 。
现在,所有的页面都默认加上了布局模板。
六、设置默认命名空间引用
上面的例子,在App.razor 和Index.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
?
?
|