Blazor一个简单的示例让我们来起飞
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一个简单的示例让我们来起飞的更多相关文章
- 使用Express创建一个简单的示例
1.安装Express 使用npm包安装工具来安装Express安装包,打开npm命令行,输入: npm install -g express 2.创建一个工程 本示例是在windows下创建的,项目 ...
- Postman----登录接口返回的reponse中token值传递给其他接口的一个简单接口测试示例
注: 在进行接口测试时,我们都需要使用登录,并且其他的接口都要在登录后进行,那么必不可少的会使用到将登录接口的reponse返回结果中的某些参数值需要进行返回,并传递给其他接口,这样才可以进行登录后的 ...
- mxnet:基础知识和一个简单的示例
NDArray与NumPy的多维数组类似,但NDArray提供了更多的功能:GPU和CPU的异步计算:自动求导.这使得NDArray能更好地支持机器学习. 初始化 from mxnet import ...
- 一个简单的示例在spring boot中实现国际化
最近在网上找了一个有关账单管理的spring boot项目,其中有一部分是涉及显示国际化信息的,即将页面上的中英文进行转换.因为在这之前这部分内容没有接触过,所以在这记录下过程. 中文效果图如下所示: ...
- Hibernate操作指南-搭建一个简单的示例(基于Java Persistence API JPA)
- Hibernate操作指南-搭建一个简单的示例(基于原生API和注解)
- Hibernate操作指南-搭建一个简单的示例(基于原生API和XML)
- python+requests----登录接口reponse中token传递给其他接口使用的一个简单小示例介绍
#!/usr/bin/env python # coding=UTF-8 import requests def login(): url = "https://xxxx.xxx.xxx/v ...
- IDDD 实现领域驱动设计-一个简单的 CQRS 示例
上一篇:<IDDD 实现领域驱动设计-CQRS(命令查询职责分离)和 EDA(事件驱动架构)> 学习架构知识,需要有一些功底和经验,要不然你会和我一样吃力,CQRS.EDA.ES.Saga ...
随机推荐
- Python设计模式(5)-代理模式
# coding=utf-8 # 代理模式:# * 代理类成为实际想调用对象的中间件,可以控制对实际调用对象的访问权限# * 可以维护实际对象的引用 class DbManager: def __in ...
- 支持向量机SVM推导
样本(\(x_{i}\),\(y_{i}\))个数为\(m\): \[\{x_{1},x_{2},x_{3}...x_{m}\} \] \[\{y_{1},y_{2},y_{3}...y_{m}\} ...
- App 开发中判断 ios 和 andriod 常用方法便于修复在两类机型样式不一样等缺陷
判断安卓, ios
- 利用Ajax实现异步请求
Ajax 1.课程引入 静态网站和动态网站都是同步的,但同步方式有缺点:页面请求响应式阻塞,影响用户体验 为了解决这个问题,可以通过变通的手段实现页面的局部更新(隐藏帧),由于隐藏 ...
- 如何假装黑客,使用python去批量破解朋友的网站密码
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取http ...
- L25词嵌入进阶GloVe模型
词嵌入进阶 在"Word2Vec的实现"一节中,我们在小规模数据集上训练了一个 Word2Vec 词嵌入模型,并通过词向量的余弦相似度搜索近义词.虽然 Word2Vec 已经能够成 ...
- 5. git 过滤,让某文件夹里无法提交新添加的文件
. gitignore 向此文件里添加文件路径就行了.如( web/core/ ) 此时git status将看不到添加的文件或文件夹了
- jmeter元件的执行顺序
元件的执行顺序 在同一作用域范围内,test plan中的元件按照以下顺序执行:1) Config Elements--配置元件2) Pre-porcessors --前置处理器3) Timer-定时 ...
- Linux学习笔记(九)Vim文本编辑器的使用
Vim文本编辑器的使用 Vim的工作模式 1.命令模式 2.输入模式 3.编辑模式 进入Vim 1.使用Vim打开文件 2.直接进入指定位置 Vim基本命令 1.插入命令 2.光标移动命令 3.使用V ...
- 实战 | 将Apache Hudi数据集写入阿里云OSS
1. 引入 云上对象存储的廉价让不少公司将其作为主要的存储方案,而Hudi作为数据湖解决方案,支持对象存储也是必不可少.之前AWS EMR已经内置集成Hudi,也意味着可以在S3上无缝使用Hudi.当 ...