BlazorBlazor他是一個開源的Web框架,不,這不是重點(diǎn),重點(diǎn)是它可以使c#開發(fā)在瀏覽器上運(yùn)行Web應(yīng)用程序.它其實(shí)也簡化了SPA的開發(fā)過程.
為什么選擇Blazor?Blazor可以讓.NET附有全棧開發(fā)功能,它可以使Web開發(fā)變得輕松而高效.而且Blazor是開源的,它得到了社區(qū)的大力支持,而且發(fā)展速度會很快. 它還擁有SPA的一些功能比如:
創(chuàng)建應(yīng)用![]() 如果說無法在看到Blazor WebAssembly App那么執(zhí)行如下命令即可. dotnet new -i Microsoft.AspNetCore.Components.WebAssembly.Templates::3.2.0-preview5.20216.8 項目結(jié)構(gòu)如下所示 我們可以看到上圖中的項目結(jié)構(gòu)
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類,我們可以看到在開發(fā)模式下,啟動Blazor調(diào)試,并且我們可以看到我們通過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如下所示我創(chuàng)建了一個列表頁面,在代碼中我們可以看到@page他定義了該頁面的url,當(dāng)然在razor中也是這樣的,而且下最下面我通過HttpClient進(jìn)行我們的api調(diào)用,在這 System.Net.Http.Json這篇文章中我們也可以看到他簡直就是為了我們blazor而生的大大減少了我們的代碼量. 而且在我的代碼中最后一部分有一個@functions片段,它包含了頁面所有的業(yè)務(wù)邏輯,在我們頁面初始化時我們通過OnInitializedAsync方法進(jìn)行調(diào)用我們的api然后將其進(jìn)行填充賦值并填充到我們的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中的參數(shù)傳遞到我們的@functions代碼中,在Id上面指定 [Parameter] 屬性,該屬性指定的就是url中的參數(shù)值.在這我們通過使用 @bind 來將我們的html組件和類對象進(jìn)行雙向綁定. @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方法中,可以在依賴項注入容器中注冊本地服務(wù)。 public class Startup { public void ConfigureServices(IServiceCollection services) { } public void Configure(IComponentsApplicationBuilder app) { app.AddComponent<App>("app"); } } BlazorWebAssemblyHost可以用于在DI容器中定義接口和實(shí)現(xiàn)。 public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) => BlazorWebAssemblyHost.CreateDefaultBuilder() .UseBlazorStartup<Startup>(); } Blazor可以基于服務(wù)端運(yùn)行但是需要注意服務(wù)端的話需要為每一個客戶端打開連接,并且我們必須一直與服務(wù)端保持連接才行.如果說切換到WebAssembly客戶端版本,限制是完全不同的,但是目前來說的話他首次需要下載一些運(yùn)行時文件到瀏覽器中. 通過如上代碼我們可以看到一個簡單的blazor應(yīng)用程序的建立,詳細(xì)代碼的話大家可以看一下github倉庫中的內(nèi)容.通過源碼的話直接啟動BlazorServerCRUDSample.Server即可,希望可以通過本示例幫助到你~共同學(xué)習(xí)共同進(jìn)步. |
|