我以前常苦勸只會用 WebForm Server-Side Event 寫網頁的同事:JavaScript 一定要學好學滿,Flash 已被賈伯斯賜死,Silverlight 也隨風而逝,在這 HTML5 時代唯有 JavaScript 才是王道,逃避不學 JavaScript 只會 C# 跟人家寫什麼網頁?

說來好笑,時間來到 2018 年。啪! 我被打臉。不學 JavaScript 只懂 C# 也能寫 HTML5 網頁,搞不好真的會實現~

故事是這樣的,2015 年,Google、微軟、Mozilla、WebKit 團隊等幾位網際網路界大腕,約好要來推動一種叫做 WebAssembly 的新技術。傳統瀏覽器是在執行階段將 JavaScript 編譯成 ByteCode 後執行,WebAssmbly 則允許開發者事先將程式碼編譯成 ByteCode,以 WebAssebmly 形式載入執行。編譯過的 WebAssembly 具有體積小,載入與執行速度快的優點,而最最美妙的一點,開發者可以選擇自己熟悉的語言開發 WebAssembly,不再侷限 JavaScript 一種語言。對微軟而言,最佳 WebAssembly 開發語言自然是 C#,而融合 WebAssembly 開發網頁的新技術叫 Blazor。換句話說,Silverlight 那個可以用 C# 寫前端的美好年代即將捲土重來,而這次 WebAssembly 是現代瀏覽器都支援的標準,不必擔心跨不出作業系統瀏覽器坐困愁城。(依 Can I use... 的統計,除了 IE、Opera Mini、黑莓機、QQ/百度這些又老又舊的瀏覽器之外,電腦手機平板都支援)

延伸閱讀:

Blazor 仍處於實驗階段,何時可以產品化,甚至能否正式推出都是未知數,但目前看到的成果已讓人十分興奮。抱著參加研討會的心態,看了影片讀了文件,有了基本概念,順便整理筆記如下。(註:筆記圖片出自參考影片及文件,不再一一註明。)

參考資料:

上面這張圖揭示 WebAssembly 在瀏覽器扮演的角色。傳統做法是 JavaScript 經過解析、編譯,最後交給 JIT Intepreter 執行。而 WebAssembly 允許你用 C++/RUST/GO/.NET 語言開發程式編成 .wasm 直接交由 JIT Interpreter 執行。

Blazor 的名稱來自 Browser + Razor (B"L"而非B"R"是為了唸起來好聽 XD),概念上沿用 ASP.NET MVC cshtml 的 Razor 語法,一樣在網頁中穿插 HTML 與程式碼,但跟 ASP.NET MVC Razor 的差別在於 MVC Razor 是在伺服器端執行轉成 HTML 送至瀏覽器,而 Blazor cshtml 的 C# 程式碼則是在瀏覽器裡執行。Blazor Framework 架構如上圖,mono.js 是以 JavaScript 寫的 Mono Runtime,支援在瀏覽器端跑 .NET;blazor.js 則是 JavaScript 與 WebAssembly 的溝通橋樑,讓網頁程式可以呼叫 WebAssebmly DLL 函式,讓 WebAssembly 可以呼叫 JavaScript 函式。netstandard.dll 提供 .NET Standard 程式庫 API、app.dll 則是預先編譯好的專案程式碼。

不意外地,Visaul Studio 2017 是開發 Blazor 的最佳工具,Blazor 的專案架構跟 ASP.NET Core 超像,連 Startup.cs / Program.cs 寫法也大同小異。

你可以選擇將 Blazor 專案建置成一堆靜態檔,放在任何網站伺服器(例如:Apache、Nginx、Github...)讓使用者下載執行,也可以選擇用 Blazor + ASP.NET Core + Shared Library 專案模版。後者的好處是 ASP.NET Core 專案可自動將 Blazor 編譯結果放在網站供使用者下載,Shared Library 主要用來定義資料型別(POCO / DTO)或公用函式供 Blazor 與 WebAPI 共用,這也符合一般 Client 與 Server 集中共用邏輯的設計實務。

Blazor 的 cshtml 長得像這樣:

@page "/customer-list"
@using Services
@inject IDataAccess DataRepository

<ul>
    @if (Customers != null)
    {
        @foreach (var customer in Customers)
        {
            <li>
                <CustomerDisplay FirtName=customer.FirstName LastName=customer.LastName />
            </li>
        }
    }
</ul>

@functions {
    private IReadOnlyList<Customer> Customers;

    protected override async Task OnInitAsync()
    {
        // The property DataRepository received an implementation
        // of IDataAccess through dependency injection. Use 
        // DataRepository to obtain data from the server.
        Customers = await DataRepository.GetAllCustomersAsync();
    }
}

@page 宣告路由,@inject 注入服務元件,HTML 元素中穿插 Razor 語法,而 @function 區塊是 C# 程式,概念跟 MVC 相似,但 C# 程式是在瀏覽器內執行,修改 Customers 內容後上方的 @foreach (var customer in Customers) 立即重跑更新。而 Blazor 也傾向用自訂元件(Component,如上面出現的 <CustomerDisplay />)重複利用邏輯及組成網頁,種種概念都跟 Knockout.js、AngularJS、Vue.js 等 MVVM 框架相同,但用 C# 寫前端 MVVM 就是爽。

Blazor Project 可封裝 CSHTML、CSS、JS、C# 程式庫,方便包成 Package 重複使用或透過 NuGet 分享。

在 Blazor 裡 .NET 與 JavaSript 可透過 Interop 方式互動,JavaScript 呼叫 .NET 端函式:

DotNet.invokeMethodAsync('BlazorSample', 'ReturnArrayAsync')
.then(data => {
  data.push(4);
    console.log(data);

C# 呼叫 JavaScript 端函式:

JSRuntime.Current.InvokeAsync<string>(
            "exampleJsFunctions.displayWelcome",
            welcomeMessage);

偵錯工具方面,Blazor 整合了 Chrome DevTools Protocol,透過偵錯 Proxy 提供簡單的 F10 Step-by-Step 偵錯、本地變數檢視及 Callstack 資訊。


圖片來源:WHAT IS BLAZOR?

Blazor 最酷的一點是透過 mono.js 與 Mono WebAssembly 在瀏覽器端打造出 .NET Runtime,.NET Standard 程式庫不需轉換以 .dll 形式載入即可,意思是,.dll 元件可以直接從伺服器端搬到瀏覽器端執行?

影片裡對此做了火力展示 - 一個純 Client Side 的 Markdown 編輯器,神奇的 Markdown 即時預覽功能來自 NuGet 套件 - Markdig。只要元件支援 .NET Standard,原本只能在伺服器完成的事有可能搬進瀏覽器裡執行,這是 Blazor 技術最令人興奮之處。

看完以上的介紹,讓我們一起加入敲碗的行列,期待 Blazor 的美麗新世界早日實現。

註:如果你現在的開發工作仍以 WebForm 為主,有些功課可以先做:學好 ASP.NET MVC csthml Razor 語法、開始改用 .NET Core / .NET Standard 寫程式庫、熟悉 ASP.NET Core 專案架構,這些知識將有助於與 Blazor 接軌,即便最後 Blazor 沒能成真,技能也符合未來主流,不會吃虧的。

Blazor is still in experimental period, but the idea is quite attrractive to .NET developers, the ariticle is my survery notes.


Comments

# by 過路人

Hi 黑大,似乎會有這些模式, Blazor *Client-Side Blazor (ASP.NET Core Hosted) *Full-Stack Blazor (Server-Side in ASP.NET Core) *Server-Side https://www.telerik.com/blogs/a-breakdown-of-blazor-project-types Server-Side Blazor to Ship in .NET Core 3.0 https://visualstudiomagazine.com/articles/2018/10/03/blazor-update.aspx https://blogs.msdn.microsoft.com/dotnet/2018/10/04/update-on-net-core-3-0-and-net-framework-4-8/

# by Jeffrey

to 過路人,感謝補充。

# by jasonlhy

不過寫 JS 但也需要寫 HTML 和 CS ...

# by terenceng2010

Blazor Server已經production了。第一感覺就是webforms不用postback而用websocket的樣子。

# by Copipi

請教一下黑大, Blazor 是不是和google 的 Flutter 類似,但Flutter寫出來的可以當一般網頁,也可以發佈成手機App Blazor 是不是也能發佈成手機App?

# by Jeffrey

to Copipi,查了一下,有個 Hybrid Blazor 方案可以一魚兩吃 https://devblogs.microsoft.com/aspnet/hybrid-blazor-apps-in-mobile-blazor-bindings-july-update/

# by Becky

請問有推薦的 Blazor 免費的報表嗎?,因RDLC 不支援 .net 6

# by Jeffrey

to Becky, 我傾向找一台 IIS 跑 WebForm + ReportViewer,用前端技巧整合,繼續沿用 RDLC。https://blog.darkthread.net/blog/reportviewer-with-js/

Post a comment