2019 年 5 月

第 34 卷,第 5 期

[技術最前線]

Blazor 中的路由和路由範本

藉由Dino Esposito |2019 年

Dino Esposito值得注意的差異以往的 ASP.NET Web Form 和新式 Web 是位於 Web 伺服器閘道的路由元件存在。在 Web Form,大部分的 Web 端點會是實體檔案的資源,直接透過他們的網頁路徑叫用。

使用 ASP.NET MVC 路由元件,就能每次要求的 URL 不能對應至實體伺服器的檔案。路由器會要求的 URL 的指示執行,做為輸出,具有用戶端回應是否 HTML 檢視中,JSON 承載、 二進位資料流或其他輸出。URL 也可以包含選擇性的參數,可協助判斷要呈現的特定內容的路由器。

所有的 Web 開發架構今天有路由元件,而 Blazor 也不例外。在本文中,我將探討的實作和程式設計介面 Blazor 路由引擎。

路由引擎

Blazor 路由引擎是在用戶端執行的元件。它是實作,不過,由C#程式碼中可以找到的其中一個在瀏覽器中下載的組件,並透過 WebAssembly 處理器來執行。Blazor 應用程式中,路由器目前設定在 app.cshtml 檔案中,就像這樣:

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

下列程式碼會顯示目前 program.cs 檔案的內容。如您所見,目前它不包含任何項目至路由器引擎,但稍後發生預期的項目。或者,至少這是註解的 Visual Studio 自動產生 app.cshtml 檔案中找到的建議:

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

路由器類別取得提供的組件名稱,並搜尋它,以及所有參考的組件,Blazor 元件符合執行中要求的 URL。請注意,此路由器類別行為的特定層面可能會有所演進到模型,您不必明確地指定您想要考慮路由器的組件,未來。如此一來您不小心得到非預期的端點。

就內部而言,路由器的路由資料表會建立,並以指定的順序排序。候選項目清單將從清單中的類別中的結果路由實作 IComponent 介面瀏覽組件中,而且更重要的是,會使用路由屬性裝飾。所有收集到的路由會儲存在字典排序從最特定到最不特殊。

評估演算法為基礎的 URL 和它們在字串中的位置中探索到的區段。比方說,常值的區段是比參數區段中,更明確,並接著使用多個路由條件約束的參數區段會被視為比其他呈現的限制較少的項目更明確。此外,當它發生於 ASP.NET MVC 中,談到解析 URL 的範例,在資料表中的路由會從最到評估最不特定,搜尋便會停止在第一個相符項目。

用戶端中,路由器會在許多情況下,最常在使用者按一下連結、 表單或伺服器呼叫觸發程序的下拉式清單中的項目上的 [提交] 按鈕時,才。路由器會繫結至內部的位置變更事件和控制代碼,從用戶端,整個程序的瀏覽至新要求的路徑。不用說,路由器會介入也以程式設計方式變更應用程式的位置時。最後一點,也不能忽視,路由器記錄瀏覽器歷程記錄中任何位置變更,它會負責,以便 [上一頁] 和 [下一頁] 按鈕,可以在如使用者所預期。

路由器的戰爭:Blazor vs。Angular

長的時間,路由邏輯的實作被藏在 Web 伺服器或伺服器端架構,例如 ASP.NET 的摺疊。與 SPA 架構 — 的 Angular 是國王 — 路由器實作移動到用戶端。讓我們花點時間在合併的 Angular 路由器和仍在--「 路由器的 Blazor 執行簡短的功能比較。

重點是 Blazor 路由器,目前只提供做為路由器,用戶端的基本功能。比方說,它缺乏能夠查看路由上的授權,並建立連結時,會執行檢視轉換的位置變更。並不像 Angular 的路由器,就無法運作以非同步方式取得路由參數之後執行的解決步驟。最後的 Blazor 路由器不支援條件式的重新導向至替代的路由-某樣東西,同樣地,Angular 路由器可以執行。

它是合理預期此差異的部分將降價 Blazor 隨附為 1.0 版的時間。

路由範本

路由是繫結在一起的一份已知的 URL 模式的 URL 的程序。在 Blazor,URL 模式或路由範本會收集在路由表。查看路由屬性裝飾 Blazor 應用程式元件會填入資料表。每個這些元件的路徑會變成支援的路由範本。

目前,沒有其中一個方法來控制路由的路徑連接元件的開發人員: @page 指示詞。在 ASP.NET Core,比方說,開發人員可以定義路由明確新增至資料表以程式設計的方式,讓系統找出使用的預設路由慣例,或在控制器方法上使用屬性的候選項目。如果您使用 ASP.NET Core 應用程式中的 Razor 頁面,則您瀏覽 Blazor 開發人員完全相同的體驗 — @page 指示詞。

總而言之,每個 Blazor 元件必須指定 @page 指示詞,可透過其路由範本。Blazor 元件會編譯成.cshtml 檔案的C#實作 IComponent 介面的類別。如果 Razor 來源包含 @page 指示詞,相同的動態編譯的類別也會使用路由屬性裝飾。

值得注意 Blazor 支援多個路由指示詞,在相同的檢視。換句話說,下列程式碼提供良好的支援:

@page “/”
@page “/home”
<h1>My Home Page</h1>

探索到的所有路由會將放在相同的路由資料表容器,並依照上述的規則來排序。在上一個範例中,這兩個路由指示詞是由常值,讓它們進入最終容器的上層區域和 (相對於) 出現的順序排序。

路由並支援參數,但參數化的路由是最終的資料表中較低優先順序比常值的路由,因為認為較不明確。參數化的路由的範例如下:

@page “/user/view/{Id}”

URL 模式比對演算法的觸發程序時的 URL 包含伺服器名稱後面 /user/檢視/此路由。URL 的軌跡 /user/檢視/中的任何內容是具名的參數 {Id} 相關聯。 

如果您已熟悉 ASP.NET MVC (和良好的最大範圍內,甚至是 Web Form),此模型繫結模式應該還是很落伍。在 ASP.NET 中,路由參數會指派給相符的控制器方法的型式參數。在 Blazor,項目會是稍微不同,但比較。

在 Blazor,路由器參數會自動指派給元件使用的 [參數] 屬性的屬性。比對,就會發生的參數和屬性名稱。以下是簡單的範例:

@page “/user/view/{Id}”
<h1>Hello @Id!</h1>
@functions {
  [Parameter]
  public string Id { get; set; }
  protected override void OnInit()
  {
    // Some code here
  }
}

目前,Blazor 不支援選擇性參數,因此,如果 {Id} 中的範例 URL 遺漏,整個 URL 不相符。若要避免這個問題,最佳目前的因應措施是有兩個 @page 指示詞,如果沒有參數,與下列程式碼所示:

@page “/user/view/{Id}”
@page “/user/view/”
<h1>Hello @Id!</h1>
@functions {
  [Parameter]
  public string Id { get; set; } = “0”;
  protected override void OnInit()
  {
    // Some code here
  }
}

在此同時,您也可以提供的繫結的頁面參數會覆寫,如果透過 URL 傳遞值的預設值。

類型比對是常見的問題,使用參數化的路由和自動繫結至變數。如果 URL 的區段包含常值的字串,但繫結的變數宣告型別為 int,會發生什麼事?在一般情況下,而不需要任何預防措施,它可能會產生例外狀況,因為常值塞到整數容器。如果您必須先確定只有特定類型的值會指定其中一個參數必須是,您應該選擇路由條件約束。

路由條件約束是如果您已熟悉的 ASP.NET MVC 的任何類別的新執行任何動作。它包含的型別屬性加入每個 URL 參數,如下所示:

@page “/user/view/{Id:int}”

參數的名稱被後面接著冒號符號並參考.NET 型別為常值。支援的常值符合一對一的大部分.NET 基本類型: datetime、 長度和 decimal、 bool、 double、 float、 int。路由條件約束,使其失效的比對任何無法成功轉換成指定類型的參數值以及路由無法辨識。

更聰明的連結和以程式設計方式的 URL 導覽

Blazor 應用程式中,歡迎您使用錨點標籤,以建立連結至外部內容。不過,當錨定標記用來呈現功能表或導覽列中,一些額外的工作可能需要調整 CSS 樣式,並反映之連結的狀態。

每當錨定項目是必要的但特別是在功能表中,可以使用內建的 Blazor NavLink 元件。標準的 HTML 錨定項目和 NavLink 元件之間的差異會處於 「 作用中 」 樣式自動指派,目前的地址相符的連結時。「 作用中 」 的 CSS 類別會自動加入到錨定標記呈現 NavLink 元件,如果目前網頁的 URL 比對參考的 URL。「 作用中 」 的 CSS 類別的實作會維持網頁開發人員的責任。此元件也會包含控制如何完成比對的屬性。您可以執行嚴格的相符項目或前置詞相符項目。

Blazor 路由器也會以程式設計方式觸發。若要透過從 Blazor 頁面內的程式碼巡覽,您應該先插入 IUriHelper 抽象類型的設定相依性。@ 插入指示詞的執行作業,如下所示:

@inject Microsoft.AspNetCore.Blazor.Services.IUriHelper Navigator

插入的物件可以讓透過 NavigateTo 方法。此方法採用 URL 做為引數:

Navigator.NavigateTo(“/user/view/1”);

方法是概念上相當於在純 JavaScript DOM 位置物件的 href 屬性。在 Blazor,不過,路由器會神奇的瀏覽,而不需要離開用戶端,而不需要完全重新載入來自伺服器的內容。

遺漏的項目

Blazor framework 是吸引人的軟體,但其中一個保留中的運作方式非常相似。有許多遺漏路由功能 — 比方說,將角色或使用者的身分識別新增至路由的能力 — 以及驗證和授權是仍未完成。解決在路由中的安全性相關功能的任何考量必須等候到這些 Api 會完成。

另一個重要的東西路由遺失:能夠完全自訂的目標 URL 的相關決定路由器的邏輯。這項功能會幫助開發人員取得無效的連結要求的控制權。雖然 Blazor 路由器遠從完成時,工作會繼續朝向成熟,傳送架構。您可以檢視增強功能的小組所追蹤的路由系統 Blazor bit.ly/2TtY0DP


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

感謝下列 Microsoft 技術專家來檢閱這篇文章:Daniel Roth


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