日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

ASP.NET Core Blazor 初探之 Blazor Server

發布時間:2023/12/4 asp.net 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core Blazor 初探之 Blazor Server 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上周初步對Blazor WebAssembly進行了初步的探索(ASP.NET Core Blazor 初探之 Blazor WebAssembly)。這次來看看Blazor Server該怎么玩。

Blazor Server

Blazor 技術又分兩種:

  • Blazor WebAssembly

  • Blazor Server

Blazor WebAssembly上次已經介紹過了,這次主要來看看Blazor Server。Blazor Server 有點像WebAssembly的服務端渲染模式。頁面在服務器端渲染完成之后,通過SignalR(websocket)技術傳輸到前端,再替換dom元素。其實不光是頁面的渲染,大部分計算也是服務端完成的。Blazor Server模式可以讓一些不支持WebAssembly的瀏覽器可以運行Blazor項目,可是問題也是顯而易見的,基于SignalR的雙向實時通信給網絡提出了很高的要求,一旦用戶量巨大,對服務端的水平擴容也帶來很大的挑戰,Blazor Server的用戶狀態都維護在服務端,這對服務端內存也造成很大的壓力。
我們還是以完成一個簡單的CRUD項目為目標來探究一下Blazor Server究竟是什么。因為前面Blazor Webassembly已經講過了,相同的東西,比如數據綁定,屬性綁定,事件綁定等內容就不多說了,請參見ASP.NET Core Blazor 初探之 Blazor WebAssembly。

新建Blazor Server項目

打開vs找到Blazor Server模板,看清楚了不要選成Blazor Webassembly模板。

看看生成的項目結構:

可以看到Blazor Server的項目結構跟ASP.Net Core razor pages 項目是一模一樣的。看看Startup是怎么配置的:

public class Startup{public Startup(IConfiguration configuration){Configuration = configuration;}public IConfiguration Configuration { get; }// This method gets called by the runtime. Use this method to add services to the container.// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940public void ConfigureServices(IServiceCollection services){services.AddRazorPages();services.AddServerSideBlazor();services.AddSingleton<WeatherForecastService>();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IWebHostEnvironment env){if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}else{app.UseExceptionHandler("/Error");// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseEndpoints(endpoints =>{endpoints.MapBlazorHub();endpoints.MapFallbackToPage("/_Host");});}}

主要有2個地方要注意:在ConfigureServices方法里注冊了Blazor的相關service:

services.AddServerSideBlazor();

在Configure方法的終結點配置了Blazor相關的映射:

endpoints.MapBlazorHub();

上次Blazor Webassembly我們的數據服務是通過一個Webapi項目提供的,這次不用了。如果需要提供webapi服務,Blazor Server本身就可以承載,但是Blazor Server根本不需要提供webapi服務,因為他的數據交互都是通過websocket完成的。

實現數據訪問

新建student類:

public class Student{public int Id { get; set; }public string Name { get; set; }public string Class { get; set; }public int Age { get; set; }public string Sex { get; set; }}

上次我們實現了一個StudentRepository,我們直接搬過來:

public interface IStudentRepository{List<Student> List();Student Get(int id);bool Add(Student student);bool Update(Student student);bool Delete(int id);} } public class StudentRepository : IStudentRepository{private static List<Student> Students = new List<Student> {new Student{ Id=1, Name="小紅", Age=10, Class="1班", Sex="女"},new Student{ Id=2, Name="小明", Age=11, Class="2班", Sex="男"},new Student{ Id=3, Name="小強", Age=12, Class="3班", Sex="男"}};public bool Add(Student student){Students.Add(student);return true;}public bool Delete(int id){var stu = Students.FirstOrDefault(s => s.Id == id);if (stu != null){Students.Remove(stu);}return true;}public Student Get(int id){return Students.FirstOrDefault(s => s.Id == id);}public List<Student> List(){return Students;}public bool Update(Student student){var stu = Students.FirstOrDefault(s => s.Id == student.Id);if (stu != null){Students.Remove(stu);}Students.Add(student);return true;}}

注冊一下:

services.AddScoped<IStudentRepository, StudentRepository>();

實現學生列表

跟上次一樣,先刪除默認生成的一些內容,減少干擾,這里不多說了。在pages文件夾下新建student文件夾,新建List.razor文件:

@page "/student/list" @using BlazorServerDemo.Model @using BlazorServerDemo.Data @inject IStudentRepository Repository <h1>List</h1> <p class="text-right"><a class="btn btn-primary" href="/student/add">Add</a> </p> <table class="table"><tr><th>Id</th><th>Name</th><th>Age</th><th>Sex</th><th>Class</th><th></th></tr>@if (_stutdents != null){foreach (var item in _stutdents){<tr><td>@item.Id</td><td>@item.Name</td><td>@item.Age</td><td>@item.Sex</td><td>@item.Class</td><td><a class="btn btn-primary" href="/student/modify/@item.Id">修改</a><a class="btn btn-danger" href="/student/delete/@item.Id">刪除</a></td></tr>}} </table> @code {private List<Student> _stutdents;protected override void OnInitialized(){_stutdents = Repository.List();} }

這個頁面是從上次的WebAssembly項目上復制過來的,只改了下OnInitialized方法。上次OnInitialized里需要通過Httpclient從后臺獲取數據,這次不需要注入HttpClient了,只要注入Repository就可以直接獲取數據。
運行一下:

F12看一下這個頁面是如何工作的:

首先/student/list是一次標準的Http GET請求。返回了頁面的html。從返回的html代碼上來看綁定的數據已經有值了,這可以清楚的證明Blazor Server技術使用的是服務端渲染技術。

_blazor?id=Fv2IGD6CfKpQFZ-fi-e1IQ連接是個websocket長連接,用來處理服務端跟客戶端的數據交互。

實現Edit組件

Edit組件直接從Webassembly項目復制過來,不用做任何改動。

@using BlazorServerDemo.Model <div><div class="form-group"><label>Id</label><input @bind="Student.Id" class="form-control" /></div><div class="form-group"><label>Name</label><input @bind="Student.Name" class="form-control" /></div><div class="form-group"><label>Age</label><input @bind="Student.Age" class="form-control" /></div><div class="form-group"><label>Class</label><input @bind="Student.Class" class="form-control" /></div><div class="form-group"><label>Sex</label><input @bind="Student.Sex" class="form-control" /></div><button class="btn btn-primary" @onclick="TrySave">保存</button><CancelBtn Name="取消"></CancelBtn> </div> @code{[Parameter]public Student Student { get; set; }[Parameter]public EventCallback<Student> OnSaveCallback { get; set; }protected override Task OnInitializedAsync(){if (Student == null){Student = new Student();}return Task.CompletedTask;}private void TrySave(){OnSaveCallback.InvokeAsync(Student);} }

實現新增頁面

同樣新增頁面從上次的Webassembly項目復制過來,可以復用大量的代碼,只需改改保存的代碼。原來保存代碼是通過HttpClient提交到后臺來完成的,現在只需要注入Repository調用Add方法即可。

@page "/student/add" @using BlazorServerDemo.Model @using BlazorServerDemo.Data @inject NavigationManager NavManager @inject IStudentRepository Repository <h1>Add</h1> <Edit Student="Student" OnSaveCallback="OnSave"></Edit> <div class="text-danger">@_errmsg </div> @code {private Student Student { get; set; }private string _errmsg;protected override Task OnInitializedAsync(){Student = new Student(){Id = 1};return base.OnInitializedAsync();}private void OnSave(Student student){Student = student;var result = Repository.Add(student);if (result){NavManager.NavigateTo("/student/list");}else{_errmsg = "保存失敗";}} }

這里不再多講綁定屬性,綁定事件等內容,因為跟Webassembly模式是一樣的,請參見上一篇。
運行一下 :

我們的頁面出來了。繼續F12看看頁面到底是怎么渲染出來的:

這次很奇怪并沒有發生任何Http請求,那么我們的Add頁面是哪里來的呢,讓我們繼續看Websocket的消息:

客戶端通過websocket給服務端發了一個消息,里面攜帶了一個信息:OnLocation Changed "http://localhost:59470/student/add",服務端收到消息后把對應的頁面html渲染出來通過Websocket傳遞到前端,然后前端進行dom的切換,展示新的頁面。所以這里看不到任何傳統的Http請求的過程。
點一下保存看看發生了什么:

我們可以看到點擊保存的時候客戶端同樣沒有發送任何Http請求,而是通過websocket給后臺發了一個消息,這個消息表示哪個按鈕被點擊了,后臺會根據這個信息找到需要執行的方法,方法執行完后通知前端進行頁面跳轉。
但是這里有個問題,我們填寫的數據呢?我們在文本框里填寫的數據貌似沒有傳遞到后臺,這就不符合邏輯了啊。想了下有可能是文本框編輯的時候數據就提交回去了,讓我們驗證下:

我們一邊修改文本框的內容,一邊監控websocket的消息,果然發現了,當我們修改完焦點離開文本框的時候,數據直接被傳遞到了服務器。厲害了我的軟,以前vue,angularjs實現的是前端html跟js對象的綁定技術,而Blazor Server這樣就實現了前后端的綁定技術,666啊。

實現編輯跟刪除頁面

這個不多說了使用上面的知識點輕松搞定。
編輯頁面:

@page "/student/modify/{Id:int}" @using BlazorServerDemo.Model @using BlazorServerDemo.Data @inject NavigationManager NavManager @inject IStudentRepository Repository <h1>Modify</h1> <Edit Student="Student" OnSaveCallback="OnSave"></Edit> <div class="text-danger">@_errmsg </div> @code {[Parameter]public int Id { get; set; }private Student Student { get; set; }private string _errmsg;protected override void OnInitialized(){Student = Repository.Get(Id);}private void OnSave(Student student){Student = student;var result = Repository.Update(student);if (result){NavManager.NavigateTo("/student/list");}else{_errmsg = "保存失敗";}} }

刪除頁面:

@page "/student/delete/{Id:int}" @using BlazorServerDemo.Model @using BlazorServerDemo.Data @inject NavigationManager NavManager @inject IStudentRepository Repository <h1>Delete</h1> <h3>確定刪除(@Student.Id)@Student.Name ? </h3> <button class="btn btn-danger" @onclick="OnDeleteAsync">刪除 </button> <CancelBtn Name="取消"></CancelBtn> @code {[Parameter]public int Id { get; set; }private Student Student { get; set; }protected override void OnInitialized(){Student = Repository.Get(Id);}private void OnDeleteAsync(){var result = Repository.Delete(Id);if (result){NavManager.NavigateTo("/student/list");}} }

運行一下:

總結

Blazor Server總體開發體驗上跟Blazor Webassembly模式保持了高度一直。雖然是兩種不同的渲染模式:Webassembly是客戶端渲染,Server模式是服務端渲染。但是微軟通過使用websocket技術作為一層代理,巧妙隱藏了兩者的差異,讓兩種模式開發保持了高度的一致性。Blazor Server除了第一次請求使用Http外,其他數據交互全部通過websocket技術在服務端完成,包括頁面渲染、事件處理、數據綁定等,這樣給Blazor Server項目的網絡、內存、擴展等提出了很大的要求,在項目選型上還是要慎重考慮。

最后demo的源碼:BlazorServerDemo

關注我的公眾號一起玩轉技術

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的ASP.NET Core Blazor 初探之 Blazor Server的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。