Blazor

Blazor他是一个开源的Web框架,不,这不是重点,重点是它可以使c#开发在浏览器上运行Web应用程序.它其实也简化了SPA的开发过程.

Blazor = Browser + Razor

为什么选择Blazor?

Blazor可以让.NET附有全栈开发功能,它可以使Web开发变得轻松而高效.而且Blazor是开源的,它得到了社区的大力支持,而且发展速度会很快.

它还拥有SPA的一些功能比如:

  • 路由
  • 依赖注入
  • 服务端渲染
  • Layout

    等等

创建应用

如果说无法在看到Blazor WebAssembly App那么执行如下命令即可.

dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0-preview5.20216.8

项目结构如下所示

我们可以看到上图中的项目结构

  • BlazorServerCRUDSample.Client:该项目工程中包含了客户端的相关代码页面等文件
  • BlazorServerCRUDSample.Server:该项目工程中包含了webapi.
  • BlazorServerCRUDSample.Shared:该类库中用于存放客户端和服务端之间的共享代码.

BlazorServerCRUDSample.Server

控制器代码如下所示

    [Route("api/[controller]")]
public class StudentController : Controller
{
private readonly Shared.Data.AppContext _dbcontext; public StudentController(Shared.Data.AppContext dbcontext)
{
this._dbcontext = dbcontext;
}
[HttpGet]
public async Task<List<Student>> Get()
{
return await _dbcontext.Students.AsQueryable().ToListAsync();
}
[HttpGet("{id}")]
public async Task<Student> Get(int id)
{
return await _dbcontext.Students.FindAsync(id);
}
[HttpPost]
public async Task Post([FromBody] Student student)
{
student.CreateTime = DateTime.Now;
if (ModelState.IsValid)
await _dbcontext.AddAsync(student);
await _dbcontext.SaveChangesAsync();
}
[HttpPut]
public void Put([FromBody] Student student)
{
if (ModelState.IsValid)
_dbcontext.Update(student);
_dbcontext.SaveChanges();
}
[HttpDelete("delete/{id}")]
public void Delete(int id)
{
var entity = _dbcontext.Students.Find(id);
_dbcontext.Students.Remove(entity);
_dbcontext.SaveChanges();
} }
    public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
} public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseConfiguration(new ConfigurationBuilder()
.AddCommandLine(args)
.Build())
.UseStartup<Startup>()
.Build();
}

对于Startup类,我们可以看到在开发模式下,启动Blazor调试,并且我们可以看到我们通过UseClientSideBlazorFiles来启动我们的客户端Startup


public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
} public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddResponseCompression();
services.AddDbContext<AppContext>(options =>
{
options.UseSqlServer("Data Source=.;Initial Catalog=BlazorServerCRUDSample;User ID=sa;Password=sa;MultipleActiveResultSets=true;");
});
} // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseResponseCompression(); if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBlazorDebugging();
} app.UseStaticFiles();
app.UseClientSideBlazorFiles<Client.Startup>(); app.UseRouting(); app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
});
}
}

BlazorServerCRUDSample.Client

如下所示我创建了一个列表页面,在代码中我们可以看到@page他定义了该页面的url,当然在razor中也是这样的,而且下最下面我通过HttpClient进行我们的api调用,在这 System.Net.Http.Json这篇文章中我们也可以看到他简直就是为了我们blazor而生的大大减少了我们的代码量.

而且在我的代码中最后一部分有一个@functions片段,它包含了页面所有的业务逻辑,在我们页面初始化时我们通过OnInitializedAsync方法进行调用我们的api然后将其进行填充赋值并填充到我们的html中.

@page "/fetchstudent"
@inject HttpClient Http
@using BlazorServerCRUDSample.Shared.Models <h1>Students</h1>
<p>
<a href="/addstudent">Create New</a>
</p>
@if (students == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class='table'>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>CreateTime</th>
</tr>
</thead>
<tbody>
@foreach (var student in students)
{
<tr>
<td>@student.Id</td>
<td>@student.Name</td>
<td>@student.Description</td>
<td>@student.CreateTime</td>
<td>
<a href='/editstudent/@student.Id'>Edit</a> |
<a href='/delete/@student.Id'>Delete</a>
</td>
</tr> }
</tbody>
</table>
} @functions {
Student[] students;
protected override async Task OnInitializedAsync()
{
students = await Http.GetJsonAsync<Student[]>("api/student");
}
}

如下代码中我们还是对我们的页面提供了url,其中Id是将从url中的参数传递到我们的@functions代码中,在Id上面指定 [Parameter] 属性,该属性指定的就是url中的参数值.在这我们通过使用 @bind 来将我们的html组件和类对象进行双向绑定.

@page "/editstudent/{Id}"
@inject HttpClient Http
@using BlazorServerCRUDSample.Shared.Models
@inject Microsoft.AspNetCore.Components.NavigationManager Navigation <h2>Edit Student</h2>
<hr />
<div class="row">
<div class="col-md-4">
<form @onsubmit="@(async () => await UpdateStudent())">
<div class="form-group">
<label for="Name" class="control-label">Name</label>
<input for="Name" class="form-control" @bind="@student.Name" />
</div>
<div class="form-group">
<label asp-for="Description" class="control-label">Description</label>
<textarea asp-for="Description" class="form-control" @bind="@student.Description"> </textarea>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
<input type="submit" value="Cancel" @onclick="@cancel" class="btn btn-warning" />
</div>
</form>
</div>
</div> @functions {
[Parameter]
public string id { get; set; }
public Student student = new Student();
protected override async Task OnInitializedAsync()
{
student = await Http.GetJsonAsync<Student>("/api/Student/" + Convert.ToInt32(id));
}
protected async Task UpdateStudent()
{
await Http.SendJsonAsync(HttpMethod.Put, "api/Student", student);
Navigation.NavigateTo("/fetchstudent");
}
void cancel()
{
Navigation.NavigateTo("/fetchstudent");
}
}

在ConfigureServices方法中,可以在依赖项注入容器中注册本地服务。

   public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
} public void Configure(IComponentsApplicationBuilder app)
{
app.AddComponent<App>("app");
}
}

BlazorWebAssemblyHost可以用于在DI容器中定义接口和实现。

    public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
} public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
BlazorWebAssemblyHost.CreateDefaultBuilder()
.UseBlazorStartup<Startup>();
}

Blazor可以基于服务端运行但是需要注意服务端的话需要为每一个客户端打开连接,并且我们必须一直与服务端保持连接才行.如果说切换到WebAssembly客户端版本,限制是完全不同的,但是目前来说的话他首次需要下载一些运行时文件到浏览器中.

通过如上代码我们可以看到一个简单的blazor应用程序的建立,详细代码的话大家可以看一下github仓库中的内容.通过源码的话直接启动BlazorServerCRUDSample.Server即可,希望可以通过本示例帮助到你~共同学习共同进步.

Reference

https://github.com/hueifeng/BlazorCRUDSample

https://www.cnblogs.com/shanyou/p/12825845.html

Blazor一个简单的示例让我们来起飞的更多相关文章

  1. 使用Express创建一个简单的示例

    1.安装Express 使用npm包安装工具来安装Express安装包,打开npm命令行,输入: npm install -g express 2.创建一个工程 本示例是在windows下创建的,项目 ...

  2. Postman----登录接口返回的reponse中token值传递给其他接口的一个简单接口测试示例

    注: 在进行接口测试时,我们都需要使用登录,并且其他的接口都要在登录后进行,那么必不可少的会使用到将登录接口的reponse返回结果中的某些参数值需要进行返回,并传递给其他接口,这样才可以进行登录后的 ...

  3. mxnet:基础知识和一个简单的示例

    NDArray与NumPy的多维数组类似,但NDArray提供了更多的功能:GPU和CPU的异步计算:自动求导.这使得NDArray能更好地支持机器学习. 初始化 from mxnet import ...

  4. 一个简单的示例在spring boot中实现国际化

    最近在网上找了一个有关账单管理的spring boot项目,其中有一部分是涉及显示国际化信息的,即将页面上的中英文进行转换.因为在这之前这部分内容没有接触过,所以在这记录下过程. 中文效果图如下所示: ...

  5. Hibernate操作指南-搭建一个简单的示例(基于Java Persistence API JPA)

  6. Hibernate操作指南-搭建一个简单的示例(基于原生API和注解)

  7. Hibernate操作指南-搭建一个简单的示例(基于原生API和XML)

  8. python+requests----登录接口reponse中token传递给其他接口使用的一个简单小示例介绍

    #!/usr/bin/env python # coding=UTF-8 import requests def login(): url = "https://xxxx.xxx.xxx/v ...

  9. IDDD 实现领域驱动设计-一个简单的 CQRS 示例

    上一篇:<IDDD 实现领域驱动设计-CQRS(命令查询职责分离)和 EDA(事件驱动架构)> 学习架构知识,需要有一些功底和经验,要不然你会和我一样吃力,CQRS.EDA.ES.Saga ...

随机推荐

  1. xftp连接centos7

    1.下载xftp文件,并正常进行安装 2.安装好之后运行,并新建会话,此时可见如下界面: 注意: 名称,可随便输入,自己能看懂是什么就行      主机,输入当前Linux服务器的ip(如何获取服务器 ...

  2. 广告行业中那些趣事系列9:一网打尽Youtube深度学习推荐系统

    最新最全的文章请关注我的微信公众号:数据拾光者. 摘要:本篇主要分析Youtube深度学习推荐系统,借鉴模型框架以及工程中优秀的解决方案从而应用于实际项目.首先讲了下用户.广告主和抖音这一类视频平台三 ...

  3. csdn的垃圾体验

    微信扫码登录网页csdn,每次扫码都是csdn有关的不同的公众号,必须关注才可以登录,为了推广公众号真是简直了 无法修改id 注销也需要扫码,这次是必须下载csdn的app才能注销,我真是服了,我都要 ...

  4. Geber文件,装配图,BOM表的输出

    一.Geber文件的输出步骤: 注:选择需要导出的层 注:所指箭头的地方都多加个零,让输出有更大的空间来容纳 总结:这就是最终的Geber文件了 二.NC   Drill file的输出: 三.IPC ...

  5. 3. JS生成32位随机数

    function randomWord ( randomFlag,min,max ) { var str = " ", range = min, arr = ['0','1','2 ...

  6. Java实现链表(个人理解链表的小例子)

    1.单链表和数组的区别 数组:数组的存储空间是连续的,需要事先申请空间确定大小,通过下标查找数据,所以查找速度快,但是增加和删除速度慢 链表:离散存储,不需要事先确定大小,通过头指针加遍历查找数据,查 ...

  7. 两种异常(CPU异常、用户模拟异常)的收集

    Windows内核分析索引目录:https://www.cnblogs.com/onetrainee/p/11675224.html 两种异常(CPU异常.用户模拟异常)的收集  文章的核心:异常收集 ...

  8. 21.SpringCloud实战项目-后台题目类型功能(网关、跨域、路由问题一文搞定)

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  9. 2、flink入门程序Wordcount和sql实现

    一.DataStream Wordcount 代码地址:https://gitee.com/nltxwz_xxd/abc_bigdata 基于scala实现 maven依赖如下: <depend ...

  10. window servet 2012 r2 配置php服务器环境

    绑定:https://jingyan.baidu.com/article/0bc808fc2c6a851bd485b92a.html 配置环境:http://www.jb51.net/article/ ...