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. threejs 鼠标移动控制模型旋转

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  2. Python中有许多HTTP客户端,但使用最广泛且最容易的是requests

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:北京尚脑软件测试 PS:如有需要Python学习资料的小伙伴可以加点击 ...

  3. S - Primitive Primes CodeForces - 1316C 数学

    数学题 在f(x)和g(x)的系数里找到第一个不是p的倍数的数,然后相加就是答案 为什么? 设x1为f(x)中第一个不是p的倍数的系数,x2为g(x)...... x1+x2前的系数为(a[x1+x2 ...

  4. 美化你的终端利器Iterm2

    Iterm2是特别好用的一款终端,支持自定义字体和高亮,让日常开发,充满愉悦. 安装iterm2(mac版) brew tap caskroom/cask brew cask install iter ...

  5. DeepinV20系统文件管理器右键发送至为知笔记

    1. 创作背景 昨天在深度系统上做了一个打开文件管理器选择文件右键发送文本至博客园的插件. 这个插件对于我自己来说是及其方便的东西,平时的学习积累,工作经验或者生活感悟,随手记下之后,就能够轻松发送出 ...

  6. API加密框架monkey-api-encrypt发布1.2版本

    框架介绍 monkey-api-encrypt 是我之前写的一个API加密的框架,主要是将加密/解密的逻辑交给框架实现,等数据到达Controller后自动解密了,让开发人员不需要关注数据的加解密操作 ...

  7. go获取当前项目下所有依赖包

    在设置好GOPATH,GOROOT的环境变量的情况下. 在项目配置好pkg.bin.src等这几个目录的情况,进入src目录. 在终端,输入:go get ./... 即可获得所有依赖包.

  8. 一、Go语言由来与关键时间线

    Go语言,又称作Golang,是Google在2009年11月开源的开发语言.是一门静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言. Go是罗伯特·格瑞史莫(Robert Griesemer ...

  9. 使用 Junit + Mockito 实践单元测试

    一.前言 相信做过开发的同学,都多多少少写过下面的代码,很长一段时间我一直以为这就是单元测试... @SpringBootTest @RunWith(SpringRunner.class) publi ...

  10. Web中间件常见漏洞

    IIS Internet Information Services--windows 解析漏洞 IIS 6.x 基于文件名:该版本默认会将 *.asp;.jpg 此种格式的文件名,当成 Asp 解析, ...