主頁 > .NET開發 > 瀏覽器中的 .Net Core —— Blazor WebAssembly 初體驗

瀏覽器中的 .Net Core —— Blazor WebAssembly 初體驗

2020-09-17 03:04:00 .NET開發

前言

       在兩年多以前就聽聞 Blazor 框架,是 .Net 之父的業余實驗性專案,其目的是探索 .Net 與 WebAssembly 的兼容性和應用前景,現在這個專案已經正式成為 Asp.Net Core 框架的一部分,公開了預覽版,官方教程也基本寫好上線了,就著這個機會,順便體驗一下這個框架用起來如何,

       之前在網上搜索 Blazor 的相關資訊的時候發現吵得很厲害,前端開發者大多覺得有 Vue 之類的前端 MVVM 框架已經夠用,沒有 C# 插足的余地,甚至很多 C# 開發者也不知道這個框架的基本作業原理,覺得是把 C# 翻譯成 js,翻譯之后就變成了類似 Vue 的東西,還有人覺得這是下一個 Flash 或者 Silverlight,毛主席曾經說過:沒有調查就沒有發言權,對于說這種話的人,我只想說,少刷幾分鐘抖音快手隨便搜下百度都能搞清楚怎么回事,作為 C# 開發者,這都理解不了我是真不知道是怎么學的 C#,難道真是傳說中的拖控制元件一把梭,然后就沒然后了?

       簡單說明下 Blazor WebAssembly 的作業原理,就是在 WebAssembly 框架的基礎上,實作了一個 .Net Core Runtime,用一個啟動 js 下載相關 dll、初始化 .Net 虛擬機、啟動虛擬機運行入口函式,接下來就和一個正常 .Net 程式一樣,該怎么運行怎么運行,用 Java 的說法就是在瀏覽器中運行的 jvm,從此,.Net 跨平臺領先 Java 一步,除了 Windows、Linux、MacOS之外,還要加上瀏覽器,悄悄說一下,瀏覽器上的運行時實作了 netstandard 2.1,待遇比傳統的 .Net Framework 還好,要說缺點就是除錯很麻煩,因為整個運行程序和服務器無關,在 VS 下斷點也沒用,不知道是預覽版沒做好還是什么原因,順便導致出問題很難跟蹤,還有改了代碼要重新編譯專案,不能像 MVC 那樣改了 cshtml 重繪下瀏覽器就生效,每次重啟除錯太耐等了,

正文

       目前 Blazor WebAssembly 還不是默認專案模板的一部分,需要自行下載模板才能在 VS 2019 的專案模板里找到,需要的可以移步官方教程,不知道有多少園友知道我有個專門收集各種各種我覺得有趣的示例代碼的專案,當然也有很多代碼是我自己寫的,我就冒出了一個想法,如何把這個專案也集成到我的現有專案中,畢竟創建獨立的專案和在現有專案中融合新東西完全是兩種感覺,很多組件一旦融合就會各種沖突打架,需要深入了解他們才能知道沖突有沒有辦法解決,要如何解決,

       經過幾天的研究,我成功把 Blazor WebAssembly 專案融合進了我的主專案,同時進行了一些改造,主要方法還是先新建一個模板專案,然后對比代碼差異,融合代碼,補充 nuget 包,接下來簡要說明下在現有 Asp.Net Core 專案中增加 Blazor WebAssembly 專案的主要步驟,在我的專案中,/blazor 是 Blazor 根目錄,各種修改都配合這個設定,各位請根據自己的情況修改,

客戶端

       1、新建一個包含 Asp.Net Core 宿主服務器的 Blazor WebAssembly 專案,純 Blazor WebAssembly 專案發布后可以放到靜態檔案服務器,宿主服務器也只是當檔案服務器用,把客戶端專案復制到主專案解決方案中,在 VS 中添加現有專案,如果修改過專案名稱和命名空間,請重啟 VS,不然可能報錯,

       2、復制共享專案到主專案的解決方案,修復專案參考,

       3、修改 wwwroot/index.html,修改 <head> 標簽中的 <base href="https://www.cnblogs.com/" /> 為 <base href="https://www.cnblogs.com/blazor" />,

       4、在 wwwroot 檔案夾新建檔案夾 blazor,把 wwwroot 下的其他檔案和檔案夾放進 wwwroot/blazor 檔案夾,避免和主專案路徑沖突,同樣地,主專案也不能再用 /blazor/xxx 了,

服務端

       1、安裝 nuget 包 Microsoft.AspNetCore.Blazor.Server,要勾上包括預發行版,不然搜不到,

       2、在主專案中參考客戶端專案和共享專案,

       3、在 Startup.ConfigureServices 中增加代碼:

1 services.AddResponseCompression(opts =>
2 {
3     opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
4         new[] { "application/octet-stream" });
5 });

       4、在 Startup.Configure 中增加 app.UseBlazorDebugging(); 如果只想在開發環境使用,自行增加 if 判斷,一般跟 app.UseDeveloperExceptionPage(); 放在一起,

       5、在 Startup.Configure 中注冊 Blazor 檔案,注意型別引數,是客戶端專案的 Program 類:

app.UseClientSideBlazorFiles<BlazorApp.Client.Program>();

       6、在 Startup.Configure 中檢查是否有并補充 app.UseStaticFiles();

       7、在 Startup.Configure 中注冊路由終結點,注意 "/blazor/{**subPath}" 這一段,表示把 blazor 映射到 /blazor/xxx 去,{**subPath} 這一段是路由終結點引數捕獲語法,里面的 subPath 可以亂寫,但不能空著不填,不然啟動不了,因為 Blazor WebAssembly 啟動之后路由都是前端完成的,跟服務器沒有任何關系,所以可以亂填,只是要滿足系統的語法要求好讓服務器能正常啟動,

1 app.UseEndpoints(endpoints =>
2 {
3     //以前的 mvc、api 等等各種注冊,
4 
5     //映射 Blazor 客戶端終結點
6     endpoints.MapFallbackToClientSideBlazor<BlazorApp.Client.Program>("/blazor/{**subPath}", "index.html");
7 });

       至此,融合作業完成,可以正常啟動專案并訪問 /blazor 體驗效果了,

效果預覽

在兩個瀏覽器(Chrome、Edge by Chromium)分別登錄不同賬號,分別使用 Blazor WebAssembly SignalR .Net Core Client 和 SignalR Javascript Client 連接 SignalR 服務,手機(Edge Android)再登錄另一個賬號使用 Blazor WebAssembly SignalR .Net Core Client 連接 SignalR 服務(域名是花生殼域名做 DDNS),實作跨平臺跨終端實時聊天,運行在 Release 發布模式,

 

 結語

       總體來說,Blazor 的體驗還是很不錯的,整體風格和 Asp.Net Core 幾乎一摸一樣,我看見的一瞬間就感覺非常親切,依賴注入系統也可以正常使用,只是區別是 Scope 生命周期的實際效果和單例是一樣的,因為整個應用就只有一個 Scope,但是 Blazor Server Side 就有區別了,每個 SignalR 連接系結一個 Scope,掉線重連成功也會恢復到原先的 Scope ,一直連不上太久就不行了,整個服務器行程包含一個單例,所以在注冊的時候盡量用 Scope,避免單例成習慣,緩不過來,

       Razor 語法也是個神一樣的設計,最初是作為 MVC3 的視圖引擎推出,在 MVC4 成為默認引擎,好像 MVC5 取消了 aspx 視圖引擎支持,.Net Core 徹底取消了和 aspx 有關的一切東西,現在,Razor 又成為了一個前端渲染框架,真是老樹發新芽,又是一春,在 html 模板渲染上,我用下來就是 Razor 的 @ 和 Vue 的雙花括號語法特別順手,aspx 那種尖括號語法實在看的頭昏腦脹,本來 html 就各種尖括號,還要再來一堆尖括號,VS 高亮都看得頭疼,更別說一般文本編輯器打開了,根本看不懂,到底誰和誰是一對?Razor 就特別爽,代碼和標記自動識別切換,區域代碼塊,區域變數,比起 Vue 是有過之而無不及(Vue 的變數作用域師從 js,是真的暈),

       根據目前使用的情況來看,只要不包含涉及系統底層呼叫的庫都可以正常使用,比如和行程、執行緒、硬體驅動相關、本機 dll 互操作這種,

       我在模板專案中,增加了 SignalR 客戶端使用示例,也是根據官方教程修改,而且使用的客戶端庫就是普通 .Net 客戶端庫,和控制臺、桌面程式用是同一套 dll,微軟果然神,到底是怎么把網路相關的 API 底層實作神不知鬼不覺地的換掉的,默認注入的 HttpClient 也是 System.Net.Http 命名空間的,

       由于網路通信底層實際上是依賴瀏覽器,所以瀏覽器會自動把 HttpClient 的請求嫁接到瀏覽器上,相關的 Headers、Cookies 自然也會自動攜帶上,所以如果 Blazor 應用和普通網頁在同一個域,這些東西實際上會共享,我的身份認證相關功能就是利用這個特點偷懶實作的,如果不在同一個域,最簡單實用的方法就是用 IdentityServer4 作為認證服務,客戶端參考 nuget 包 IdentityModel,這個包會給 HttpClient 增加一堆用來和 OpenId Connect、OAuth2.0 協議互動的擴展方法,當作兩個程式用開放協議配合作業來寫就行,用 IdentityModel 擴展獲取 Access Token,請求的時候把 Token 加進 HttpClient 的 Headers,當然也可以用 IdentityModel 的擴展來注入,更方便,

       對于 SPA 應用來說,狀態管理一定是無法繞過的,不過在 Blazor 中,直接用依賴注入來管理狀態就可以了,如果需要重繪頁面也不丟失狀態的話,可以考慮使用 ILocalStorage 服務來持久化狀態,或者其他持久化方案也行,反正支持 js 互操作,先隨便封裝一個應急,等 C# 的原生組件出來了再看怎么辦,

       與服務器的互動除了常規的 Web Api,還有內部預覽階段的 gRPC-Web,等這東西搞定了,Blazor 極限使用一切二進制資料,那效率不知道能提升多少,Asp.Net Core 3.0 全面支持 HTTP2,Chrome 好像從 70 往后也都支持 HTTP2,gRPC-Web 原生使用 HTTP2 肯定比現在包一層兼容層支持 HTTP1.1 來的好,可以說在瀏覽器的限制下,能做的應該都差不多,不知道以后瀏覽器會不會開放執行緒介面讓 WebAssembly 使用內核執行緒執行計算密集型任務(好像會更方便黑客把瀏覽器當礦機啊,開放的問題也是多的不行,感覺瀏覽器就是個黑暗森林,網站服務器要防用戶搞破壞,用戶也要防網站用腳本搞破壞,這個猜疑鏈也導致瀏覽器各種限制,難啊),

        作為一個雜食性開發者,對于 Blazor 與 Vue 的爭論這種東西我是無所謂的,只要在我的知識范圍內在我能接受的開發復雜度內解決問題,其他的都是浮云,就像鄧爺爺說的:實踐是檢驗真理的唯一標準;管他黑貓白貓,抓到耗子就是好貓;這才是我的信條,徹底的實用主義,

       啊,C# 這種強型別安全語言進入前端領域有點激動,不注意就說了一大通,被 js 那詭異的物件型別,動態作用域坑的實在是不行,敲鍵盤的時候心虛不知道會不會莫名其妙突然就出問題,實在是對心臟不好,還是喜歡 C#,什么東西都清晰明了,不埋暗坑,外加 DLR 和 dynamic,真是進可攻、退可守,js 完全沒有退路,實在是傷不起,

       在最后發布以后才發現 Blazor 聊天進不去,除錯正常,試了N多辦法都沒搞定,最后洗掉發布檔案夾中的所有 dll,關閉 VS,洗掉 obj、bin 檔案夾,重新發布才正常,真是坑爹,

 

       2020-5-26 更新:已經更新到候選版,遷移方法參見博文:Blazor WebAssembly 候選版遷移手記,

 

       轉載請完整保留以下內容并在顯眼位置標注,未經授權洗掉以下內容進行轉載盜用的,保留追究法律責任的權利!

  本文地址:https://www.cnblogs.com/coredx/p/12342936.html

  完整源代碼:Github

  里面有各種小東西,這只是其中之一,不嫌棄的話可以Star一下,

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/61627.html

標籤:.NET Core

上一篇:Asp.net Core MVC(三)UseMvc設定路由

下一篇:.NET Core MVC下的TagHelper

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more