2019 年 2 月

第 34 卷,第 2 期

本文章是由機器翻譯。

[技術最前線]

搞定 Blazor 中的表單

藉由Dino Esposito |2019 年 2 月

Dino EspositoASP.NET Core Blazor 是C#為基礎的用戶端的架構,來建置單一頁面應用程式 (Spa)。在這方面,不是太大的 Angular,在於它可以互動的任何後端可能有公開 HTTP 連線的端點。不過,在此階段中,Blazor 是進行中和遠離上線工作。

話雖如此,Blazor 的某些部分 ASP.NET Core 3.0 的一部分傳送。Razor 元件是完全在伺服器執行,與傳統的 ASP.NET Core 應用程式可能會構成其後端並存 Blazor 應用程式的特殊設定。後端工作最常用於傳統的 Web 應用程式的共存和相異 Blazor 型展示層上的 ASP.NET 伺服器可簡化某些程式設計的情況下,會建立一種純 SPA 方法與單純之間的折衷伺服器的方法。在本文中,我將討論如何處理輸入的表單和用戶端-伺服器通訊。讓我們開始快速問卷調查的 Razor 元件。

伺服器端 Blazor

Blazor 是設計來接收和處理事件,不論周遭環境的核心架構。目前,唯一完全支援的案例執行 Blazor 內裝載的瀏覽器的 UI 執行緒和 ASP.NET Core 執行階段內。其他實際案例尚未有執行 Blazor Web 背景工作角色內或甚至在某些 desktop 啟用的平台,例如 Electron。Web 背景工作 」 中託管而使得 Blazor 適當的平台,漸進式和離線 Web 應用程式,同時在這類平台也是合理的 Electron 中裝載。例如,讓我們簡短地比較指示非常基本的 Electron 啟動 (請參閱https://github.com/electron/electron-quick-start) 與新的伺服器端 Blazor 專案執行時,會發生什麼事。

Electron 的快速入門的原始程式碼包含下列方法:

function createWindow () { 
  mainWindow = new BrowserWindow({width: 
    800, height: 600}) 
  mainWindow.loadFile(‘index.html’)
}

方法負責建立瀏覽器視窗並載入個別的 HTML 檔案。接下來的情況只持續的訊息交換之間外界 (瀏覽器) 和最內層命令介面 (HTML 網頁)。架構位於之間就會適當地處理 proxy 處理訊息的負擔。讓我們來看看會發生什麼事的伺服器端 Blazor 應用程式執行時,如所述**[圖 1**。

「 載入 」 階段的伺服器端 Blazor 應用程式
[圖 1 伺服器端 Blazor 應用程式的 「 載入 」 階段

首先,瀏覽器載入的應用程式層級 index.html 檔案,定義的主頁面配置 (主要標頭標記),並下載的一部分,也會載入名為 blazor.server.js 的小型 JavaScript 檔案。交涉 _blazor/逐步**[圖 1指出的目前瀏覽器的主機環境與 Blazor 應用程式之間建立一個 ASP.NET Core SignalR 的連線。最後,連線會升級到 Web 通訊端。此動作會在 [Fiddler] 畫面中所擷取的最後一個步驟[圖 1**。

在這兩種情況下,主機環境載入初始設定式檔案。一旦建立連線之後,應用程式邏輯執行,並會產生任何必要的 HTML。在伺服器端 Blazor 所產生的 HTML 伺服器端會比較目前呈現的 dom,實際更新 DOM 的所需片段。透過 SignalR 連線,執行所有更新。

擷取在瀏覽器中的使用者按一下移的其他方式。相關的事件封裝,並且傳送伺服器端,它們是在此所 Blazor JavaScript interop 層處理,而且在處理C#程式碼。

Visual Studio 隨附於伺服器端 Blazor 應用程式的臨機操作的專案範本。一般專案會包含用戶端專案和 ASP.NET Core 專案。最有可能會想要新增.NET Standard 程式庫專案來保存必須在前端和後端之間共用的類別。

設定用戶端應用程式

用戶端應用程式的啟動類別是幾乎是空白的:

public class Startup
{
  public void ConfigureServices(IServiceCollection services)
  {
  }

  public void Configure(IBlazorApplicationBuilder app)
  {
    app.AddComponent<App>(“app”);
  }
}

唯一必要的變更會插入 HttpClient 的參考,以便任何 Blazor 頁面能夠進行 HTTP 的遠端呼叫:

public void ConfigureServices(IServiceCollection services)
{
  services.AddScoped<HttpClient>();
}

用戶端應用程式最相關的加法是元件,可讓使用者填妥並張貼的表單。在 [ [圖2您會看到應用程式註冊的使用者] 按鈕所產生的 UI。它是一個純文字的簡單 HTML 表單收集使用者的電子郵件地址和密碼,並將它傳遞回遠端後端。

範例表單
[圖 2 範例表單

有趣的事是您要產生的容器中的輸入欄位的標記**[圖 2**。即使容器將逐步引導,叫起來也類似 HTML 的表單,它不是,則為 true 的 HTML 表單,如中所示**[圖 3**。

[圖 3 標記,以產生的 (非 HTML) 表單

<div class=”col-sm-6 col-md-4 offset-md-4”>
  <h3 class=”text-center login-title”>I Want To Be a New User</h3>
  <div class=”account-wall”>
    <div class=”form-signin”>
      <input type=”text” 
                   class=”form-control” 
                   name=”email” bind=”@Email” />
      <input type=”password” 
                   class=”form-control” 
                   name=”password” bind=”@Password” />
      <button class=”btn btn-primary 
                     onclick=”@TryRegister”>
        Sign me in
      </button>
    </div>
    <div class=”text-center”>@Message</div>
  </div>
</div>

如您所見,標記是純 HTML,但沒有 FORM 項目不需要。最後,C#用戶端上執行的程式碼會負責收集輸入的值,因此向前他們的遠端端點的 (不一定) ASP.NET 後端。

您會看到相關聯與虛擬的表單和 Blazor 用戶端頁面的屬性之間的繫結的輸入項目保證雙向繫結屬性。TryRegister 函式會負責將內容張貼至後端。[圖 4顯示用戶端頁面的 @functions 區塊的程式碼。

圖 4] @functions 區塊

@inject HttpClient Http...
@functions
{
  public string Email { get; set; }
  public string Password { get; set; }
  public string Message = “?”;

  public async Task TryRegister()
  {
    var input = new RegisterUserViewModel(Email, Password);
    try
    {
      var response = await Http.PostJsonAsync<CommandResponse>(
        “.../account/register”, input);
      if (response.Success)
        Message = response.Message;
    }
    catch (Exception e)
    {
      Console.WriteLine(e);
      throw;
    }
  }
}

輸入欄位的內容中的資料傳輸物件的新執行個體蒐集 — RegisterUserViewModel — 並透過 HttpClient PostJsonAsync 方法序列化為 JSON。後端會接收 HTTP POST 要求,在其中將主體設定,如下所示:

{“email”:”...”,”password”:”...”}

在伺服器端 Blazor 應用程式後端通常是 ASP.NET Core 應用程式。在此情況下,要求會轉送至其中的模型繫結適用於控制器端點。如此一來,張貼的資料會擷取 RegisterUserViewModel 類別相同的伺服器端執行個體。不過,要注意的是後, 端不需要一定就是 ASP.NET Core 應用程式。您在透過 HttpClient 呼叫中指定的 URL 必須是絕對 URL,可以將資料公佈至幾乎任何地方,包括一些舊版 Visual Basic 基礎後端。

設定伺服器應用程式

在範例應用程式中,伺服器應用程式會是純 ASP.NET Core 保護的 Web API,當您想要保護任何這類的 Web API。比方說,它可能會對未經授權的存取,透過 JWT 權杖中,我們也可使用非 Web 用戶端,包括桌上型電腦和行動裝置用戶端保護。現在,我們只假設 Web API 允許匿名存取。您需要成功接收及處理任何 Blazor 張貼資料的程式碼如下:

public class AccountController : Controller
{
  [HttpPost]
  public IActionResult Register(
    [FromBody] RegisterUserViewModel input)
  {
    // Some work here      ...
    return Json(CommandResponse.Ok.AddMessage(“Done”));
  }
}

FromBody 屬性扮演著關鍵的角色。沒有任何呼叫端點,朝 Blazor 用戶端運作,方法會擲回的模型繫結的例外狀況。

FromBody 屬性指示 ASP.NET Core 執行階段參數繫結至傳入的 HTTP 要求主體中找到的資料。請注意,有最多可達每個動作的一個參數會使用 [FromBody 屬性裝飾。

ASP.NET Core 會將委派的處理要求的資料流至專用的格式器類別的責任。這是 JsonInputFormatter 預設類別。也請注意,一旦要求資料流已讀取的參數,它無法讀取一次的另一個參數。資料流指標,事實上,有進階到主體的結尾,而且不能移回。

Web API 的回應是另一個 Blazor 用戶端接收和還原序列化,就像這樣的 JSON 回應:

var response = await 
  Http.PostJsonAsync<CommandResponse>(absoluteUrl, input);

在此程式碼片段中,CommandResponse 型別的執行個體還原序列化回應,如果它原來是不可能,會擲回例外狀況。

在 [安全性和驗證文字

Blazor 的用戶端部分會執行在沙箱中相同的方式,JavaScript 程式碼會執行。Server 後端完全中斷從用戶端的連線,且只有在條件中連線到後端定義。Blazor 用戶端應用程式必須符合任何安全性層級與您已備妥周圍的後端。在這方面,Blazor 是一般的 Web 用戶端呼叫 Web API。它可能會透過 cookie 中,進行驗證,但是比較可能需要透過 JWT 持有人權杖進行驗證。

伺服器端 Blazor 案例可能是另一回事,它可能讓替代的情況下進行驗證和授權的意義。沒有是否已做出決策尚未在此時間點,但您可以快速了解上在討論bit.ly/2CdS74c。關鍵就在於,某些內建的 API,提供簡化的伺服器端 Blazor 應用程式,以及其他常見的驗證作業,例如復原密碼,並與內部互動登入和登出表單建立程序成員資格系統。可以,Blazor 會以某種方式納入內建 UI 的 ASP.NET Core 身分識別。但是,同樣地,在撰寫本文時決定執行任何動作。

Razor 元件的優缺點

伺服器端 Blazor 或 Razor 元件,將會到達上線狀態,當它隨附於 ASP.NET Core 3.0 Blazor 的第一個部分。有些開發人員可能會生膽怯缺點。用來設定 [單純的 SPA 解決方案,Blazor 似乎太遠距從傳統的 ASP.NET Web 開發人員的程式設計體驗。此外,WebAssembly,才能執行C#在瀏覽器中的加諸的成本,以下載和初始啟動時,雖然偵錯可能會造成問題。使用伺服器端解決方案,開發經驗都更順暢,改善偵錯、 與 JIT 編譯的較大的 API。除此之外,所有的瀏覽器支援,不論其對 WebAssembly 的原生支援。對於傳統的 ASP.NET 開發人員,重新整理的使用者介面的組件會變成幾乎一樣簡單,如同在桌面應用程式。

問題在於,所有此 magic 依賴 SignalR 連線。這會帶來一些潛在的問題。首先,會有相當多的要求會透過網路。事實上,任何更新,會需要往返。第二,伺服器會強制以追蹤每個用戶端和其狀態。ASP.NET Core SignalR 也會以一項 Azure 服務的方式提供,這提供了絕佳基礎延展性和 — 但沒有人已放大,但在真實世界中嘗試它。最後,沒有任何內建的機制,尚未以還原應用程式狀態,萬一 SignalR 連線會卸除。任何持續性的解決方案是很好,但它現在所有保留給開發人員。

總而言之,SPA 模式是有點破壞性作業,許多開發人員和 Blazor 升級 SPA 模式。伺服器端 Blazor (也就是,Razor 元件) 是聰明且非干擾性的方法,若要移向的 SPA 架構的分次。這篇文章的來源根據 Blazor 0.7.0 和位於bit.ly/2EpGF8d


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

非常感謝下列技術專家檢閱這篇文章:Jonathan Miller


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