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便可,但願能夠經過本示例幫助到你~共同窗習共同進步.