2018 年 9 月

第 33 卷 9

本文章是由機器翻譯。

技術最前線-更別說 JavaScript,這裡的 Blazor

藉由Dino Esposito

Dino Esposito關於十年前主流 Web crossroad 停止。傳統上解譯,用戶端技術例如 HTML、 CSS 和 JavaScript 所即將消失,漸進式大量湧入編譯的技術和 XAML 和 C# 等語言。在此同時,似乎是準備將原生的瀏覽器環境的專用處理引擎,例如 Silverlight,它必須已安裝為個別的外掛程式。然後出現在水平的 HTML 5 的第一個草稿和不久之後,Silverlight 是 sunsetted。

為 IT 決策者搜尋切實可行的平台,適用於跨平台 Web 開發向上橫向命名為開啟的事件。HTML5 收到提升和 JavaScript 開始其撰寫復活程式。今天,Angular、 React 及 Vue 很高熱門 JavaScript 為基礎的架構,越來越多的開發團隊選擇來建置它們的前端。

Blazor 出現為 Angular/React/Vue 的可能替代方式,並感謝 WebAssembly (WASM),它會開啟要能夠利用現有的開發生態系統,包括.NET Web。因此,以上只是另一個模型-檢視-ViewModel MVVM-導向的 JavaScript 架構,Blazor 即某種程度來說,現代的嘗試改頭換面,並精簡 Silverlight 概念 — 將 C# 的威力帶到用戶端 Web 程式開發。Blazor 的核心被設計來提供強型別、 瀏覽器為基礎的環境,來建置使用 C# 和.NET Core、 代替 JavaScript 和 HTML 頂端 Razor Web 前端。不過,Blazor 不角推送 HTML 和 CSS。相反地,它會擴充 HTML 語法,同時要求不外掛程式安裝預先定義的 Razor 標記協助程式的集合。

我想要提醒 Blazor 多半仍處於發展階段,以及任何您閱讀這裡可能會大幅變更,只在幾週內。在本文中提供的程式碼根據版本 0.5.0 於 2018 年 7 月發行。

在本文中,我將討論 Blazor 應用程式的基礎系統架構,並呈現基本"Hello World"應用程式。

神奇的 Blazor

如果您來自於 Silverlight 背景,您可能會想知道如何 Blazor — 非 JavaScript 平台,可以瀏覽器中執行而不是可安裝外掛程式。答案是,它不能。Blazor 實際上需要某種形式的外掛程式,將它裝載在相容的瀏覽器。訣竅在於所謂概念外掛程式已內嵌大多數現代瀏覽器 (其過去的 12 個月發行),而且可以輕鬆地 polyfilled 透過 JavaScript 在較舊的瀏覽器中。不同於離散外掛程式如 Adobe Flash 或 Silverlight,啟用 Blazor 支援此工具會是 WASM,W3C 社群群組,其中包含的所有主要瀏覽器中開發的開放標準。

技術上來說,WASM 是一種二進位格式的堆疊基礎虛擬機器 (VM),在架構上類似於.NET CLR 和 Java 虛擬機器,但不同於 Android Dalvik VM。做為高階程式設計語言的編譯目標,WASM 有可能在網路上啟用的.NET 應用程式的部署。不過,針對此動作,橋接器會需要轉換 WASM.NET 執行階段。Blazor 過度依賴其 Mono framework 帶入 WASM xamarin 完成工作。包含在 Blazor 應用程式的.NET 程式碼執行針對 WASM,特別是編譯的 Mono 版本中所示**[圖 1**。

在瀏覽器中執行的.NET 程式碼
[圖 1 在瀏覽器中執行的.NET 程式碼

這與何不同,說 Silverlight?Silverlight 應用程式執行沙箱 komunikaci s 容器瀏覽器環境,透過在 Internet Explorer 的 ActiveX 和 NPAPI Chrome 和 Firefox 等其他瀏覽器中的特定瀏覽器的殼層中 (請參閱文件,網址bit.ly/2klDgdY)。現在,大部分的瀏覽器解除改用 WebAssembly NPAPI 的支援。Blazor 採用的許多最佳的 Silverlight 概念並將其套用搜尋 JavaScript 的替代方案的開發人員需要進行的方式。

舊版的瀏覽器呢?

開發工具到這兩個 WASM 交叉編譯程式碼,並 asm.js,也就是 JavaScript 的低階子集,是要從高階語言的編譯目標 (請參閱asmjs.org)。Blazor,特別是,退而使用 asm.js 為基礎的.NET 執行階段。然後,已部署的程式碼會執行功能偵測來決定如何執行瀏覽器中。請注意,整個 asm.js framework 目前正在進行研究和開發。

您可以瀏覽caniuse.com檢查哪一個瀏覽器版本目前支援 WASM。站台會註明,所有的瀏覽器版本 (桌面和行動裝置) 發行從 2017 年與支援它。請注意,在撰寫本文時,Blazor polyfill 已暫時無法使用 Internet Explorer。

Blazor 應用程式的結構

Blazor 應用程式是一般的.NET Standard 程式庫與 Program.Main 進入點,取得下載和瀏覽器中執行。只有在.NET 執行階段會編譯成 WASM;如同一般的.NET 應用程式,將原生執行您在 C# 中撰寫的原始程式碼。若要清除安全性考量,請注意 Blazor 的所有程式碼仍在相同的安全 JavaScript 沙箱中執行。[圖 2顯示本文的其餘部分所顯示的範例 Blazor 應用程式所下載檔案的清單。

範例 Blazor 應用程式所下載檔案
[圖 2 範例 Blazor 應用程式所下載的檔案

您在此圖中看到不同的背景色彩識別 Blazor 應用程式的存留期間的兩個不同時間。首先,將 blazor.js 和 mono.js 檔案會下載到協調下載 Mono WebAssembly 執行階段 (mono.wasm 檔案)。目前,Mono 執行階段會包含相當豐富的功能之.NET 版本的並參與 600 kb。不過,在舊版中精簡的選項,無法一小部分的大小。這是可以使用一些改進和最佳化的區域。

下載 Mono 執行階段之後, 就會開始下載實際的.NET 組件。初始化步驟可能需要一段時間,大約三秒的範例中**[圖 2**。基於這個理由,標準 Blazor Visual Studio 範本會提供專用的區域,在 「 載入 」 階段時顯示的 ui。讓我們看看一個範例應用程式。

建置範例應用程式

若要試用 Blazor,您需要.NET Core 2.1 和 Visual Studio 15.7 或更新版本。此外,您需要從 Visual Studio marketplace 安裝 Blazor 範本。範本位於 [ASP.NET Core Web 應用程式] 資料夾中。目前有三個範本,一般的用戶端 Blazor、 ASP.NET Core 裝載的應用程式和伺服器端 Blazor。讓我們一般 Blazor 應用程式不依賴任何後端環境。此案例類似於非常密切地 Angular/React 或甚至是 Silverlight 應用程式,下載並在瀏覽器中執行的一般用戶端應用程式。

如所述,Visual Studio 中的專案是根據兩個特定的 NuGet 套件的.NET Standard 2.0 主控台應用程式:Blazor.Build 和 Blazor.Browser。兩者都起因於 Microsoft.AspNetCore 命名空間。

專案是標準的.NET Core 專案 Program.cs 啟動載入器、 Startup.cs 類別,與 ASP.NET Core 應用程式,例如 wwwroot 」、 「 共用 」 及 「 頁面重新叫用的幾個資料夾。Main 方法所示,如下所示:

public class Program
{
  public static void Main(string[] args)
  {
    CreateHostBuilder(args).Build().Run();
  }
  public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
    BlazorWebAssemblyHost.CreateDefaultBuilder()
      .UseBlazorStartup<Startup>();
}

Blazor 應用程式的元件,每個組成.cshtml Razor 檔案。根據預設,.cshtml 檔案的名稱會是元件的名稱。在範例應用程式中,應用程式都是其原始程式碼位於 app.cshtml,啟動元件的名稱,如下所示:

<Router AppAssembly=typeof(Program).Assembly />

最小值,在啟動類別會指出要使用的應用程式類別。

public class Startup
{
  public void Configure(IBlazorApplicationBuilder app)
  {
    app.AddComponent<App>("app");
  }
}

應用程式的模組只會設定 Blazor router 元件。在傳統的 Web sites (例如 ASP.NET),路由會在伺服器上,但在單一頁面應用程式中就最好是透過專用的用戶端元件。在 Blazor,路由器不讓 JavaScript (因為它是在中,例如 Angular),但是,而是會剖析參考的組件,並尋找實作 IComponent 介面中的所有類別內部路由器類別的執行個體。

路由器是負責攔截所有的瀏覽活動、 向內以及向外擴展,並讓它就會發生。很明顯地,Blazor 元件應該提供路由器,以叫用它們適當地路由資訊。Blazor 支援 ASP.NET Core 的 Razor 頁面的相同 @page 標記法。此外,它會以一般 C# 撰寫的元件類別支援路由屬性。

單一頁面

通常,在單一頁面應用程式,就會從 index.html 頁面。Blazor 應用程式也不例外,而且單一頁面位於的 wwwroot 資料夾下方。單一頁面必須至少包含下列標記:

<app>
  <!—initialization markup -->
</app>
<script src="_framework/blazor.webassembly.js"></script>

應用程式項目的內容會顯示 Blazor 平台,也就是第一個區塊的清單中的檔案的初始載入期間**[圖 2**。您可以在應用程式項目,這是最常載入.gif 的任何有效的 HTML。指令碼項目會負責以動態方式下載所需的.dll 檔案。

在首頁上的實際顯示的內容由路由器和剩餘的 index.html 檔案內容找到下列指令碼項目。讓我們檢閱路由器所完成的工作。

路由器會檢查要求的 URL-已部署之網站的根目錄,並尋找已註冊的元件,可以比對根 URL。在範例專案的 Pages 資料夾會包含開頭為下列內容的 index.cshtml 檔案:

@page "/"
<h1>Hello, Blazor!</h1>
Welcome to your first BLAZOR app.

@Page 指示詞會指示需挑選範本路由器。如果 [頁面] 資料夾 (和/或根資料夾) 中找到 _ViewImports.cshtml 檔案,其內容會納入考量。在範例專案中,根資料夾中的 _ViewImports 檔案會包含一份 using 陳述式,而 _ViewImports 檔案的 Pages 資料夾內包含的版面配置範本的參考:

@layout MainLayout

接著,會處理 MainLayout.cshtml 的內容,並 @Body 預留位置會填入所選的 Razor 檢視 (index.cshtml) 的輸出。在範例專案中,版面配置檔 (在 [Shared] 資料夾中,與 ASP.NET Core 中找到) 包含典型的啟動程序 4 深色的導覽列項目。以下是該程式碼:

<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  ...
</nav>
<div class="container">
  @Body
</div>

同樣地,如果您來自於 ASP.NET MVC 背景,這種程式設計模式看起來應該很熟悉。導覽列中您通常會有連結。您可以表示透過標準的 A 和按鈕項目,或使用預先定義之其中一個項目 (或自訂) 的連結 Razor 標記協助程式。特別是,Blazor 隨附 NavLink 協助程式元件,可提供更容易使用的語法來表示可能會或可能不是純文字的 Url 的連結。在單一頁面應用程式,事實上,連結可以是任何路由器可以理解的項目。以下是使用範例應用程式的導覽列中的 Razor 程式碼片段:

<div class="collapse navbar-collapse" id="navbarNav">
  <ul class="navbar-nav">
    <NavLink class="nav-link" href="digitalclock">
      DIGITAL CLOCK
    </NavLink>
  </ul>
</div>

Href 屬性指向的 URI,可以只比對像是"digitalclock 」,個別的 CSHTML 檔案完全實作的數位時鐘元件的元件的路由。在 [頁面] 資料夾下找到 digitalclock.cshtml 檔案。

建置範例元件

Blazor 元件是獨立的 HTML 和 C# 區塊。任何必要的 CSS 會合理地命名元件本身在不同的檔案。請注意,Blazor 不會執行任何特殊 css,而且不會造成任何慣例。CSS 處理是完全是由您決定。以下是實作為啟動程序的輸入群組的數位時鐘:

<div class="clock">
  <div class="input-group">
    <span class="@currentCss">@currentTime</span>
    <div class="input-group-append">
      <button class="btn btn-primary"
              type="button"
              onclick="@startStop">@buttonAction</button>
    </div>
  </div>
</div>

CurrentCss、 currentTime 等檓 buttonAction razor 運算式參考元件檔 @functions 區段內定義的欄位。您可以看到這些這裡:

@functions {
  string currentTime = "N/A";
  string buttonAction = "N/A";
  string currentCss = "clock-notset";
  Timer timer;
  ...
}

StartStop 運算式是指計時器按一下 [停止] 或 [開始] 按鈕以啟動/停止時所叫用的方法。[圖 3呈現 DigitalClock 元件的完整程式碼。

[圖 3 C# 程式碼的 DigitalClock 元件

@functions {
  string currentTime = "N/A";
  string buttonAction = "N/A";
  string currentCss = "clock-notset";
  Timer timer;
  protected override async Task OnInitAsync()
  {
    InitTimer();
    StartTimer();
  }
  void startStop()
  {
    if (timer.Enabled)
    {
      StopTimer();
    }
    else
    {
      StartTimer();
    }
  }
  private Task TimerTick()
  {
    currentTime = DateTime.Now.ToLongTimeString();
    currentCss = "clock-working";
    this.StateHasChanged();
    return Task.CompletedTask;
  }
  private void InitTimer()
  {
    timer = new Timer(1000);
    timer.Elapsed += async (sender, e) => await TimerTick();
  }
  private void StartTimer()
  {
    buttonAction = "STOP";
    timer.Start();
  }
  private void StopTimer()
  {
    buttonAction = "START";
    timer.Stop();
  }
}

[圖 4顯示程式介面。

範例應用程式執行動作
[圖 4 中動作的範例應用程式

示範顯示數位時鐘,由.NET 計時器。資料繫結會自動針對透過明確的使用者動作 (例如,當按一下按鈕時),觸發的事件,但不是時產生事件以程式設計的方式,例如,透過計時器。在後者的情況下,您必須呼叫 StateHasChanged 強制重新整理檢視的瀏覽器轉譯器的方法。以下是數位時鐘 Blazor 元件內之計時器刻度處理常式的程式碼:

private Task TimerTick()
{
  currentTime = DateTime.Now.ToLongTimeString();
  currentCss = "clock-working";
  this.StateHasChanged();
  return Task.CompletedTask;
}

完整的原始程式碼,請參閱bit.ly/2LVeCxA

總結

Blazor 是即將推出的實驗性架構,用於建置。以.NET 為基礎單一頁面應用程式透過 WebAssembly 瀏覽器中執行。WebAssembly 是部署原生二進位檔相容的瀏覽器的沙箱化方式 — 基本上是所有的瀏覽器隨附 2017。Blazor 使用 Razor 和 C# 來設計檢視,並包含路由器和其他熱門的 JavaScript 架構最可組合的使用者介面。

本文提供的用戶端應用程式的基礎。在即將推出的資料行,我將探討與特定的 ASP.NET Core 後端和 Blazor 擴充性點的整合。您可以深入了解 Blazor 中Jonathan Miller 的文章,引導您下載 JSON 資料從 HTTP 端點的用戶端應用程式很必要的工作。


Dino Esposito有 20 個以上的書籍和 1,000 的文章,他 25 年職涯中撰寫。作者的 「 休假中斷,「 電影樣式節目,Esposito 正在將擁有更為環保的世界的軟體撰寫成在 BaxEnergy 數位策略家。在 Twitter 上關注與他連絡: @despos

感謝閱本篇文章的下列技術專家:Daniel Roth (Microsoft),Jonathan Miller


MSDN Magazine 論壇中的這篇文章的討論