Blazor他是一个开源的Web框架,不,这不是重点,重点是它能够使c#开发在浏览器上运行Web应用程序.它其实也简化了SPA的开发过程.html
Blazor = Browser + Razorgit
Blazor可让.NET附有全栈开发功能,它能够使Web开发变得轻松而高效.并且Blazor是开源的,它获得了社区的大力支持,并且发展速度会很快.github
它还拥有SPA的一些功能好比:web
若是说没法在看到Blazor WebAssembly App那么执行以下命令便可.c#
dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0-preview5.20216.8
项目结构以下所示api
咱们能够看到上图中的项目结构浏览器
控制器代码以下所示app
[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"); }); } }
以下所示我建立了一个列表页面,在代码中咱们能够看到@page他定义了该页面的url,固然在razor中也是这样的,并且下最下面我经过HttpClient进行咱们的api调用,在这 System.Net.Http.Json这篇文章中咱们也能够看到他简直就是为了咱们blazor而生的大大减小了咱们的代码量.async
并且在个人代码中最后一部分有一个@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便可,但愿能够经过本示例帮助到你~共同窗习共同进步.