小提示
本內容節錄自《Blazor for ASP NET Web Forms Developers for Azure》電子書,可以從 .NET Docs 取得,也可以免費下載 PDF 離線閱讀。
ASP.NET Web Forms 應用程式是由 .aspx 檔案中定義的頁面所組成。 每個頁面的位址是以專案中的實體檔案路徑為基礎。 當瀏覽器對頁面提出要求時,頁面的內容會在伺服器上動態轉譯。 頁面的渲染同時考慮了 HTML 標記和伺服器控制項。
在 中 Blazor,應用程式中的每個頁面都是元件,通常是在 .razor 檔案中定義,並具有一或多個指定的路由。 路由主要在客戶端進行,而不需要涉及特定的伺服器請求。 瀏覽器會先對應用程式的根位址提出要求。 然後,應用程式中的Router根Blazor元件會處理攔截流覽要求,並將其轉送至正確的元件。
Blazor 也支援 深層連結。 當瀏覽器向應用程式根目錄以外的特定路由提出要求時,就會發生深層連結。 路由至伺服器的深層連結請求會轉發至 Blazor 應用程式,然後在客戶端路由至正確的元件。
ASP.NET Web Forms 中的簡單頁面可能包含下列標記:
Name.aspx
<%@ Page Title="Name" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Name.aspx.cs" Inherits="WebApplication1.Name" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<div>
What is your name?<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />
</div>
<div>
<asp:Literal ID="Literal1" runat="server" />
</div>
</asp:Content>
Name.aspx.cs
public partial class Name : System.Web.UI.Page
{
protected void Button1_Click1(object sender, EventArgs e)
{
Literal1.Text = "Hello " + TextBox1.Text;
}
}
應用程式中的對等頁面 Blazor 看起來會像這樣:
Name.razor
@page "/Name"
@layout MainLayout
<div>
What is your name?<br />
<input @bind="text" />
<button @onclick="OnClick">Submit</button>
</div>
<div>
@if (name != null)
{
@:Hello @name
}
</div>
@code {
string text;
string name;
void OnClick() {
name = text;
}
}
建立頁面
若要在 Blazor 中建立頁面,請建立元件,並新增 @page Razor 指令來指定元件的路由。 指令 @page 採用一個參數,即要新增至該元件的路由範本。
@page "/counter"
需要路由範本參數。 不同於 ASP.NET Web Forms,無法從其檔案位置推斷至Blazor元件的路由(雖然未來可能會新增該功能)。
路由範本語法是用於 ASP.NET Web Forms 中路由的相同基本語法。 路由參數是使用大括弧在範本中指定。 Blazor 會將路由值系結至具有相同名稱的元件參數(不區分大小寫)。
@page "/product/{id}"
<h1>Product @Id</h1>
@code {
[Parameter]
public string Id { get; set; }
}
您也可以指定路由參數值的條件約束。 例如,若要將產品識別碼限制為 int:
@page "/product/{id:int}"
<h1>Product @Id</h1>
@code {
[Parameter]
public int Id { get; set; }
}
如需 所支援 Blazor之路由條件約束的完整清單,請參閱 路由條件約束。
路由器元件
中的 Blazor 路由是由 Router 元件處理。 元件 Router 通常用於應用程式的根元件 (App.razor)。
<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
元件 Router 會在指定的 AppAssembly 和選擇性的 AdditionalAssemblies中探索可路由的元件。 當瀏覽器導航時,Router會攔截導航。若路由符合位址,則以擷取的Found呈現其RouteData參數的內容;否則,Router將呈現其NotFound參數。
RouteView 元件會處理渲染 RouteData 指定的相符元件,如果該元件有配置,則會使用其布局。 如果相符的元件沒有配置版面,則會使用選擇性指定的 DefaultLayout 。
元件 LayoutView 會在指定的佈局中呈現其子內容。 我們將在本章稍後更詳細地查看版面配置。
導航
在 ASP.NET Web Forms 中,您會將重新導向回應傳回至瀏覽器,以觸發流覽至不同的頁面。 例如:
protected void NavigateButton_Click(object sender, EventArgs e)
{
Response.Redirect("Counter");
}
通常無法在Blazor中傳回重新導向回應。 Blazor 不會使用要求-回復模型。 不過,您可以直接觸發瀏覽器流覽,就像使用 JavaScript 一樣。
Blazor提供的NavigationManager服務可用來:
- 取得目前的瀏覽器位址
- 取得基位址
- 觸發導航
- 在地址變更時收到通知
若要瀏覽至不同的位址,請使用 NavigateTo 方法:
@page "/"
@inject NavigationManager NavigationManager
<button @onclick="Navigate">Navigate</button>
@code {
void Navigate() {
NavigationManager.NavigateTo("counter");
}
}
如需所有 NavigationManager 成員的描述,請參閱 URI 和導覽狀態協助程式。
基底 URL
Blazor如果您的應用程式部署在基底路徑下,則必須使用<base>標籤在頁面元數據中指定基底 URL,以便路由傳送至工作屬性。 如果應用程式的主機頁面是使用 Razor 進行伺服器轉譯,您可以使用 ~/ 語法來指定應用程式的基位址。 如果主機頁面是靜態 HTML,則您必須明確指定基底 URL。
<base href="~/" />
頁面配置
ASP.NET 網頁窗體中的版面配置是由主版頁面處理。 主版頁面定義了一個範本,該範本包含一或多個內容佔位元,以便由各個頁面來填入內容。 主版頁面定義於 .master 檔案中,並以 指示詞開頭 <%@ Master %> 。
.master 檔案的內容會以您編寫.aspx頁面的方式進行編碼,但會新增<asp:ContentPlaceHolder>控制項來標記頁面可以提供內容的位置。
Site.master
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="WebApplication1.SiteMaster" %>
<!DOCTYPE html>
<html lang="en">
<head runat="server">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%: Page.Title %> - My ASP.NET Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
<form runat="server">
<div class="container body-content">
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
<hr />
<footer>
<p>© <%: DateTime.Now.Year %> - My ASP.NET Application</p>
</footer>
</div>
</form>
</body>
</html>
在 Blazor,您可以使用版面配置元件來處理頁面佈局。 版面配置元件繼承自 LayoutComponentBase,該元件定義了一個Body屬性,其類型為RenderFragment,可用於呈現頁面的內容。
MainLayout.razor
@inherits LayoutComponentBase
<h1>Main layout</h1>
<div>
@Body
</div>
轉譯具有版面配置的頁面時,頁面會在配置呈現其 Body 屬性所在位置的指定版面配置內容中轉譯。
若要將版面配置套用至頁面,請使用 @layout 指示詞:
@layout MainLayout
您可以使用 _Imports.razor 檔案,指定資料夾和子資料夾中所有元件的版面配置。 您也可以使用 路由器元件,為所有頁面指定預設版面配置。
主版頁面可以定義多個內容佔位元,但Blazor 中的版面配置只有一個Body 屬性。 此版面 Blazor 配置元件的限制有望在未來版本中解決。
ASP.NET Web Forms 中的主版頁面可以是巢狀的。 也就是說,一個主版頁面可以使用另一個主版頁面。 中的 Blazor 版面配置元件也可能是巢狀的。 您可以將佈局元件套用至佈局元件。 內部配置的內容將會在外部配置內呈現。
ChildLayout.razor
@layout MainLayout
<h2>Child layout</h2>
<div>
@Body
</div>
Index.razor
@page "/"
@layout ChildLayout
<p>I'm in a nested layout!</p>
接著,頁面的轉譯輸出會是:
<h1>Main layout</h1>
<div>
<h2>Child layout</h2>
<div>
<p>I'm in a nested layout!</p>
</div>
</div>
中的Blazor版面配置通常不會定義頁面 (<html>、 <body><head>、 等) 的根 HTML 元素。 根 HTML 元素會改為定義在 Blazor 應用程式的主機頁面中,用來轉譯應用程式的初始 HTML 內容(請參閱 Bootstrap Blazor)。 宿主頁面可以渲染具有包圍標記的應用程式的多個根元件。
中的 Blazor元件,包括頁面,無法轉譯 <script> 標籤。 此轉譯限制存在,因為 <script> 標籤載入一次,然後無法變更。 如果您嘗試使用Razor語法動態轉譯標記,可能會發生非預期的行為。 相反地,所有 <script> 標籤都應該新增至應用程式的主機頁面。