備註
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
Razor 元件可以整合到 Razor Pages 或 MVC 應用程式中。 轉譯頁面或檢視時,可以同時預先轉譯元件。
重要
不同 ASP.NET Core 版本的架構變更,導致本文提供了不同的指示集。 使用本文的指引之前,請確認本文頂端的檔版本選取器符合您想要用於應用程式的 ASP.NET Core 版本。
預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。
設定專案之後,請根據專案的需求使用以下幾節中的指引:
- 可以直接根據使用者要求路由的元件。 請遵循本指南,以便訪客能夠在瀏覽器中為具有
@page
指令的元件發送 HTTP 請求。 - 對於不能直接從使用者要求進行路由的元件,請參閱從頁面或檢視呈現元件一節。 當應用程式使用元件標籤協助程式將元件內嵌至現有的頁面或檢視時,請遵循此指引。
組態
使用下列指引,將 Razor 元件整合到現有 Razor Pages 或 MVC 應用程式的頁面或檢視中。
將具有下列內容的匯入檔案新增至專案的根資料夾。 將
{APP NAMESPACE}
預留位置變更為專案的命名空間。_Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using {APP NAMESPACE}
在專案的版面配置檔案中(位於
Pages/Shared/_Layout.cshtml
Pages 應用程式或Razor MVC 應用程式的Views/Shared/_Layout.cshtml
中):將下列
<base>
標籤和 HeadOutlet 標籤協助元件新增至<head>
元素:<base href="~/" /> <component type="typeof(Microsoft.AspNetCore.Components.Web.HeadOutlet)" render-mode="ServerPrerendered" />
上述範例中的
href
值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/
) 中。 如果應用程式是子應用程式,請參閱 ASP.NET Core Blazor 應用程式基底路徑。HeadOutlet 元件用於渲染頁面標題 (
<head>
元件) 和其他由 PageTitle 元件設定的標頭元素 (HeadContent 元件) 內容。 如需更多資訊,請參閱ASP.NET Core Blazor 應用程式中的標題內容控制。在
<script>
渲染區段(blazor.server.js
)之前立即為Scripts
腳本添加@await RenderSectionAsync(...)
標籤。<script src="_framework/blazor.server.js"></script>
架構會將
blazor.server.js
指令碼新增至應用程式。 無須手動將blazor.server.js
指令碼檔案新增至應用程式。
備註
通常配置會透過
_ViewStart.cshtml
檔案載入。在 Blazor Server 中註冊
Program.cs
服務,這裡是服務註冊的地點。builder.Services.AddServerSideBlazor();
將中樞 Blazor 端點新增至路由映射的
Program.cs
端點中。 將以下行放置在呼叫到MapRazorPages
(Razor Pages)或MapControllerRoute
(MVC)之後:app.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor 頁面) 或Views/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Pages:
在專案的
Index
Pages 應用程式 Razor 頁面中,新增Counter
元件的命名空間,並將元件內嵌至頁面中。 當Index
頁面載入時,Counter
元件會被預渲染在頁面中。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Pages/Index.cshtml
:@page @using {APP NAMESPACE}.Pages.Shared @model IndexModel @{ ViewData["Title"] = "Home page"; } <component type="typeof(Counter)" render-mode="ServerPrerendered" />
MVC:
在專案的 MVC 應用程式
Index
檢視中,新增Counter
元件的命名空間,並將元件內嵌至檢視中。 當Index
檢視載入時,Counter
元件會預先在頁面中渲染。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Views/Home/Index.cshtml
:@using {APP NAMESPACE}.Views.Shared @{ ViewData["Title"] = "Home Page"; } <component type="typeof(Counter)" render-mode="ServerPrerendered" />
如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。
在 Razor Pages 應用程式中使用可路由的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 Razor Pages 應用程式中支援可路由的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <p role="alert">Sorry, there's nothing at this address.</p> </NotFound> </Router>
將具有下列內容的
_Host
頁面新增至專案。 請將{APP NAMESPACE}
預留位置替換為應用程式的命名空間。Pages/_Host.cshtml
:@page @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <component type="typeof(App)" render-mode="ServerPrerendered" />
備註
上述範例假設 HeadOutlet 元件和 Blazor 指令碼 (
_framework/blazor.server.js
) 是由應用程式的配置所轉譯的。 如需詳細資訊,請參閱設定一節。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
在
Program.cs
端點中,將_Host
頁面的低優先順序路由新增為最後一個端點:app.MapFallbackToPage("/_Host");
將可路由傳送的元件新增至專案。 下列範例是以
RoutableCounter
專案範本中Counter
元件為基礎的 Blazor 元件。Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 MVC 應用程式中使用可路由傳送的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <p role="alert">Sorry, there's nothing at this address.</p> </NotFound> </Router>
將具有下列內容的
_Host
檢視新增至專案。 請將{APP NAMESPACE}
預留位置替換為應用程式的命名空間。Views/Home/_Host.cshtml
:@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <component type="typeof(App)" render-mode="ServerPrerendered" />
備註
上述範例假設 HeadOutlet 元件和 Blazor 指令碼 (
_framework/blazor.server.js
) 是由應用程式的配置所轉譯的。 如需詳細資訊,請參閱設定一節。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
將動作新增至 Home 控制器。
Controllers/HomeController.cs
:public IActionResult Blazor() { return View("_Host"); }
在
Program.cs
端點中,為傳回_Host
檢視的控制器動作新增低優先順序路由:app.MapFallbackToController("Blazor", "Home");
在 MVC 應用程式中建立
Pages
資料夾,並新增可路由傳送的元件。 下列範例是以RoutableCounter
專案範本中Counter
元件為基礎的 Blazor 元件。Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視渲染元件
本節涉及向頁面或視圖添加元件,此類元件無法由用戶請求直接路由。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
渲染有狀態的互動式元件
有狀態的互動式元件可以添加至 Razor 頁面或檢視。
當頁面或檢視渲染時:
- 元件會與頁面或視圖一起預渲染。
- 用於預先轉譯的初始元件狀態會遺失。
- 在建立 SignalR 連線時會隨即建立新的元件狀態。
以下 Razor 頁面會渲染 Counter
元件:
<h1>Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
渲染非互動式元件
在下列 Razor 頁面中,Counter
元件會使用表單指定的初始值靜態渲染。 由於元件以靜態方式轉譯,因此元件不具互動性:
<h1>Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
元件命名空間
在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml
檔案中。 在以下範例中:
- 元件會儲存在專案的
Components
資料夾中。 -
{APP NAMESPACE}
預留位置表示專案的命名空間。Components
代表資料夾的名稱。
@using {APP NAMESPACE}.Components
_ViewImports.cshtml
檔案位於 Pages
Pages 應用程式的 Razor 資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。
保存預先轉譯的狀態
若未保存預先轉譯的狀態,在預先轉譯期間所使用的狀態會遺失,而且必須在應用程式完全載入時重建。 如果任何狀態是以非同步方式設置,UI 可能會閃動,因為預渲染的 UI 被暫存的預留位置取代,然後重新完整渲染。
若要為預渲染元件保持狀態,請使用 Persist Component State Tag Helper(參考來源)。 在預先轉譯元件的應用程式中,將標籤協助程式的標籤 <persist-component-state />
新增到 </body>
頁面的結尾 _Host
標記內。
備註
通常情況下,.NET 參考來源的文件連結會載入存放庫的預設分支,這代表著下一個 .NET 版本的目前開發狀況。 若要選取特定發行版本的標籤,請使用「切換分支或標籤」下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤。
在Pages/_Host.cshtml
應用程式中的BlazorServerPrerendered
應用程式Blazor Server:
<body>
...
<persist-component-state />
</body>
使用 PersistentComponentState 服務決定要保存哪個狀態。
[SupplyParameterFromPersistentComponentState]
屬性套用至屬性時會註冊回呼,以便於預先呈現期間保存狀態,並在元件互動式渲染或服務具現化時載入。
在下列範例中 {TYPE}
,佔位元代表要儲存的數據類型(例如 , WeatherForecast[]
。
@code {
[SupplyParameterFromPersistentComponentState]
public {TYPE} Data { get; set; }
protected override async Task OnInitializedAsync()
{
Data ??= await ...;
}
}
在下列範例中,元件會在 WeatherForecastPreserveState
預先呈現期間保存氣象預報狀態,然後擷取狀態以初始化元件。
Persist Component State Tag Helper 在所有組件調用後持續保存組件狀態。
WeatherForecastPreserveState.razor
:
@page "/weather-forecast-preserve-state"
@using BlazorSample.Shared
@inject IWeatherForecastService WeatherForecastService
<PageTitle>Weather Forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (Forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in Forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
[SupplyParameterFromPersistentComponentState]
public WeatherForecast[]? Forecasts { get; set; }
protected override async Task OnInitializedAsync()
{
Forecasts ??= await WeatherForecastService.GetForecastAsync(
DateOnly.FromDateTime(DateTime.Now));
}
}
使用 PersistentComponentState 服務決定要保存哪個狀態。 PersistentComponentState.RegisterOnPersisting 會註冊回調函式,以在應用程式暫停前持續保存元件狀態。 應用程式繼續時會擷取此狀態。 在初始化程式代碼結束時進行呼叫,以避免在應用程式關機期間發生潛在的競爭狀況。
在以下範例中:
-
{TYPE}
預留位置代表要保存的資料類型 (例如WeatherForecast[]
)。 -
{TOKEN}
預留位置是狀態識別碼字串 (例如fetchdata
)。
@implements IDisposable
@inject PersistentComponentState ApplicationState
...
@code {
private {TYPE} data;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<{TYPE}>(
"{TOKEN}", out var restored))
{
data = await ...;
}
else
{
data = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson("{TOKEN}", data);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
在下列範例中,元件會在 WeatherForecastPreserveState
預先呈現期間保存氣象預報狀態,然後擷取狀態以初始化元件。
Persist Component State Tag Helper 在所有組件調用後持續保存組件狀態。
Pages/WeatherForecastPreserveState.razor
:
@page "/weather-forecast-preserve-state"
@using BlazorSample.Shared
@implements IDisposable
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState
<PageTitle>Weather Forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
nameof(forecasts), out var restored))
{
forecasts =
await WeatherForecastService.GetForecastAsync(
DateOnly.FromDateTime(DateTime.Now));
}
else
{
forecasts = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
元件在初始化時,使用與預先轉譯時相同的狀態,這樣任何耗費資源的初始化步驟只會執行一次。 轉譯的 UI 也會符合預先轉譯的 UI,因此瀏覽器中不會發生閃爍。
保存的預先呈現狀態會傳送至用戶端,用來還原元件狀態。 ASP.NET Core Data Protection 可確保在應用程式中安全地 Blazor Server 傳輸數據。
預渲染狀態大小和SignalR訊息大小限制
大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:
- SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
- 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。
若要解決該問題,請使用下列任一種方法:
- 減少放入預渲染狀態的資料量。
- 新增 SignalR 訊息大小限制。 警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。
其他 Blazor Server 資源
預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。
設定專案之後,請根據專案的需求使用以下幾節中的指引:
- 可路由的元件:指可以直接從使用者要求進行路由的元件。 請遵循本指南,以便訪客能夠在瀏覽器中為具有
@page
指令的元件發送 HTTP 請求。 - 從頁面或視圖中渲染元件:適用於使用者請求中無法直接路由的元件。 當應用程式使用元件標籤協助程式將元件內嵌至現有的頁面或檢視時,請遵循此指引。
組態
使用下列指引,將 Razor 元件整合到現有 Razor Pages 或 MVC 應用程式的頁面或檢視中。
重要
必須使用配置頁面 (_Layout.cshtml
),結合專為 元件設計的 HeadOutlet,以控制 <head>
內容,例如頁面標題 (PageTitle 元件) 和其他頭部元素 (HeadContent 元件)。 如需更多資訊,請參閱ASP.NET Core Blazor 應用程式中的標題內容控制。
在專案的配置檔案中:
將下列
<base>
標籤和 HeadOutlet 元件標籤協助程式新增至<head>
(Pages/Shared/_Layout.cshtml
Pages) 或 Razor (MVC) 中的Views/Shared/_Layout.cshtml
元素:<base href="~/" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
上述範例中的
href
值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/
) 中。 如果應用程式是子應用程式,請參閱 ASP.NET Core Blazor 應用程式基底路徑。HeadOutlet 元件用於渲染頁面標題 (
<head>
元件) 和其他由 PageTitle 元件設定的標頭元素 (HeadContent 元件) 內容。 如需更多資訊,請參閱ASP.NET Core Blazor 應用程式中的標題內容控制。請在應用程式佈局中,於
<script>
渲染區段(blazor.server.js
)之前立即為Scripts
腳本添加@await RenderSectionAsync(...)
標籤。Pages/Shared/_Layout.cshtml
(Razor 頁面) 或Views/Shared/_Layout.cshtml
(MVC):<script src="_framework/blazor.server.js"></script>
架構會將
blazor.server.js
指令碼新增至應用程式。 無須手動將blazor.server.js
指令碼檔案新增至應用程式。
將具有下列內容的匯入檔案新增至專案的根資料夾。 將
{APP NAMESPACE}
預留位置變更為專案的命名空間。_Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using {APP NAMESPACE}
在 Blazor Server 中註冊
Program.cs
服務,這裡是服務註冊的地點。builder.Services.AddServerSideBlazor();
將中樞 Blazor 端點新增至路由映射的
Program.cs
端點中。將以下行放置在呼叫到
MapRazorPages
(Razor Pages)或MapControllerRoute
(MVC)之後:app.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor 頁面) 或Views/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Pages:
在專案的
Index
Pages 應用程式 Razor 頁面中,新增Counter
元件的命名空間,並將元件內嵌至頁面中。 當Index
頁面載入時,Counter
元件會被預渲染在頁面中。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Pages/Index.cshtml
:@page @using {APP NAMESPACE}.Pages.Shared @model IndexModel @{ ViewData["Title"] = "Home page"; } <component type="typeof(Counter)" render-mode="ServerPrerendered" />
MVC:
在專案的 MVC 應用程式
Index
檢視中,新增Counter
元件的命名空間,並將元件內嵌至檢視中。 當Index
檢視載入時,Counter
元件會預先在頁面中渲染。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Views/Home/Index.cshtml
:@using {APP NAMESPACE}.Views.Shared @{ ViewData["Title"] = "Home Page"; } <component type="typeof(Counter)" render-mode="ServerPrerendered" />
如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。
在 Razor Pages 應用程式中使用可路由的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 Razor Pages 應用程式中支援可路由的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <p role="alert">Sorry, there's nothing at this address.</p> </NotFound> </Router>
將具有下列內容的
_Host
頁面新增至專案。Pages/_Host.cshtml
:@page "/blazor" @namespace {APP NAMESPACE}.Pages.Shared @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = "_Layout"; } <component type="typeof(App)" render-mode="ServerPrerendered" />
在此案例中,元件會使用共用的
_Layout.cshtml
檔案進行其配置。重要
必須使用配置頁面 (
_Layout.cshtml
),結合專為 元件設計的 HeadOutlet,以控制<head>
內容,例如頁面標題 (PageTitle 元件) 和其他頭部元素 (HeadContent 元件)。 如需更多資訊,請參閱ASP.NET Core Blazor 應用程式中的標題內容控制。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
在
Program.cs
端點中,將_Host
頁面的低優先順序路由新增為最後一個端點:app.MapFallbackToPage("/_Host");
將可路由傳送的元件新增至專案。 下列範例是以
RoutableCounter
專案範本中Counter
元件為基礎的 Blazor 元件。Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 MVC 應用程式中使用可路由傳送的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <p role="alert">Sorry, there's nothing at this address.</p> </NotFound> </Router>
將具有下列內容的
_Host
檢視新增至專案。Views/Home/_Host.cshtml
:@namespace {APP NAMESPACE}.Views.Shared @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @{ Layout = "_Layout"; } <component type="typeof(App)" render-mode="ServerPrerendered" />
元件會使用共用的
_Layout.cshtml
檔案進行其配置。重要
必須使用配置頁面 (
_Layout.cshtml
),結合專為 元件設計的 HeadOutlet,以控制<head>
內容,例如頁面標題 (PageTitle 元件) 和其他頭部元素 (HeadContent 元件)。 如需更多資訊,請參閱ASP.NET Core Blazor 應用程式中的標題內容控制。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
將動作新增至 Home 控制器。
Controllers/HomeController.cs
:public IActionResult Blazor() { return View("_Host"); }
在
Program.cs
端點中,為傳回_Host
檢視的控制器動作新增低優先順序路由:app.MapFallbackToController("Blazor", "Home");
在 MVC 應用程式中建立
Pages
資料夾,並新增可路由傳送的元件。 下列範例是以RoutableCounter
專案範本中Counter
元件為基礎的 Blazor 元件。Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視渲染元件
本節涉及向頁面或視圖添加元件,此類元件無法由用戶請求直接路由。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
渲染有狀態的互動式元件
有狀態的互動式元件可以添加至 Razor 頁面或檢視。
當頁面或檢視渲染時:
- 元件會與頁面或視圖一起預渲染。
- 用於預先轉譯的初始元件狀態會遺失。
- 在建立 SignalR 連線時會隨即建立新的元件狀態。
以下 Razor 頁面會渲染 Counter
元件:
<h1>Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
重要
必須使用配置頁面 (_Layout.cshtml
),結合專為 元件設計的 HeadOutlet,以控制 <head>
內容,例如頁面標題 (PageTitle 元件) 和其他頭部元素 (HeadContent 元件)。 如需更多資訊,請參閱ASP.NET Core Blazor 應用程式中的標題內容控制。
渲染非互動式元件
在下列 Razor 頁面中,Counter
元件會使用表單指定的初始值靜態渲染。 由於元件以靜態方式轉譯,因此元件不具互動性:
<h1>Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
重要
必須使用配置頁面 (_Layout.cshtml
),結合專為 元件設計的 HeadOutlet,以控制 <head>
內容,例如頁面標題 (PageTitle 元件) 和其他頭部元素 (HeadContent 元件)。 如需更多資訊,請參閱ASP.NET Core Blazor 應用程式中的標題內容控制。
元件命名空間
在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml
檔案中。 在以下範例中:
- 元件會儲存在專案的
Components
資料夾中。 -
{APP NAMESPACE}
預留位置表示專案的命名空間。Components
代表資料夾的名稱。
@using {APP NAMESPACE}.Components
_ViewImports.cshtml
檔案位於 Pages
Pages 應用程式的 Razor 資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。
保存預先轉譯的狀態
若未保存預先轉譯的狀態,在預先轉譯期間所使用的狀態會遺失,而且必須在應用程式完全載入時重建。 如果任何狀態是以非同步方式設置,UI 可能會閃動,因為預渲染的 UI 被暫存的預留位置取代,然後重新完整渲染。
為了解決這些問題,Blazor 支援使用維持元件狀態標籤協助程式在預渲染的頁面中維持狀態。 將標籤協助程式的標籤 <persist-component-state />
新增在結尾的 </body>
標籤內。
Pages/_Layout.cshtml
:
<body>
...
<persist-component-state />
</body>
使用 PersistentComponentState 服務決定要保存哪個狀態。 PersistentComponentState.RegisterOnPersisting 會註冊回調函式,以在應用程式暫停前持續保存元件狀態。 應用程式繼續時會擷取此狀態。 在初始化程式代碼結束時進行呼叫,以避免在應用程式關機期間發生潛在的競爭狀況。
在下列範例中,元件會在 WeatherForecastPreserveState
預先呈現期間保存氣象預報狀態,然後擷取狀態以初始化元件。
Persist Component State Tag Helper 在所有組件調用後持續保存組件狀態。
Pages/WeatherForecastPreserveState.razor
:
@page "/weather-forecast-preserve-state"
@implements IDisposable
@using BlazorSample.Shared
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState
<PageTitle>Weather Forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
nameof(forecasts), out var restored))
{
forecasts =
await WeatherForecastService.GetForecastAsync(DateTime.Now);
}
else
{
forecasts = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
元件在初始化時,使用與預先轉譯時相同的狀態,這樣任何耗費資源的初始化步驟只會執行一次。 轉譯的 UI 也會符合預先轉譯的 UI,因此瀏覽器中不會發生閃爍。
保存的預先呈現狀態會傳送至用戶端,用來還原元件狀態。 ASP.NET Core Data Protection 可確保在應用程式中安全地 Blazor Server 傳輸數據。
預渲染狀態大小和SignalR訊息大小限制
大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:
- SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
- 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。
若要解決該問題,請使用下列任一種方法:
- 減少放入預渲染狀態的資料量。
- 新增 SignalR 訊息大小限制。 警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。
其他 Blazor Server 資源
預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。
設定專案之後,請根據專案的需求使用以下幾節中的指引:
- 可路由的元件:指可以直接從使用者要求進行路由的元件。 請遵循本指南,以便訪客能夠在瀏覽器中為具有
@page
指令的元件發送 HTTP 請求。 - 從頁面或視圖中渲染元件:適用於使用者請求中無法直接路由的元件。 當應用程式使用元件標籤協助程式將元件內嵌至現有的頁面或檢視時,請遵循此指引。
組態
現有的 Razor Pages 或 MVC 應用程式可以將元件整合到 Razor 頁面或檢視中:
在專案的配置檔案中:
將下列
<base>
標籤新增至<head>
(Pages/Shared/_Layout.cshtml
Pages) 或 Razor (MVC) 中的Views/Shared/_Layout.cshtml
元素:<base href="~/" />
上述範例中的
href
值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/
) 中。 如果應用程式是子應用程式,請參閱 ASP.NET Core Blazor 應用程式基底路徑。在
<script>
轉譯區段前面新增blazor.server.js
的Scripts
指令碼標籤。Pages/Shared/_Layout.cshtml
(Razor 頁面) 或Views/Shared/_Layout.cshtml
(MVC):... <script src="_framework/blazor.server.js"></script> @await RenderSectionAsync("Scripts", required: false) </body>
架構會將
blazor.server.js
指令碼新增至應用程式。 無須手動將blazor.server.js
指令碼檔案新增至應用程式。
將具有下列內容的匯入檔案新增至專案的根資料夾。 將
{APP NAMESPACE}
預留位置變更為專案的命名空間。_Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.JSInterop @using {APP NAMESPACE}
在 Blazor Server 中註冊
Startup.ConfigureServices
服務。在
Startup.cs
中:services.AddServerSideBlazor();
將 Blazor 中樞端點新增到
app.UseEndpoints
的端點清單中 (Startup.Configure
)。Startup.cs
:endpoints.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor 頁面) 或Views/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Pages:
在專案的
Index
Pages 應用程式 Razor 頁面中,新增Counter
元件的命名空間,並將元件內嵌至頁面中。 當Index
頁面載入時,Counter
元件會被預渲染在頁面中。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Pages/Index.cshtml
:@page @using {APP NAMESPACE}.Pages.Shared @model IndexModel @{ ViewData["Title"] = "Home page"; } <div> <component type="typeof(Counter)" render-mode="ServerPrerendered" /> </div>
在上述範例中,將
{APP NAMESPACE}
預留位置取代為應用程式的命名空間。MVC:
在專案的 MVC 應用程式
Index
檢視中,新增Counter
元件的命名空間,並將元件內嵌至檢視中。 當Index
檢視載入時,Counter
元件會預先在頁面中渲染。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Views/Home/Index.cshtml
:@using {APP NAMESPACE}.Views.Shared @{ ViewData["Title"] = "Home Page"; } <div> <component type="typeof(Counter)" render-mode="ServerPrerendered" /> </div>
如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。
在 Razor Pages 應用程式中使用可路由的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 Razor Pages 應用程式中支援可路由的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
備註
針對 .NET 5.0.1 和任何其他 5.x 版本,
Router
元件中包含的一個參數為PreferExactMatches
,此參數已設定為@true
。 如需詳細資訊,請參閱 從 ASP.NET Core 3.1 移轉至 .NET 5。將具有下列內容的
_Host
頁面新增至專案。Pages/_Host.cshtml
:@page "/blazor" @{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
元件會使用共用的
_Layout.cshtml
檔案進行其配置。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
在
Startup.Configure
的Startup.cs
端點中,將_Host
頁面的低優先順序路由新增為最後一個端點:endpoints.MapFallbackToPage("/_Host");
下列範例顯示一般應用程式端點設定中新增的行:
app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
將可路由傳送的元件新增至專案。
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 MVC 應用程式中使用可路由傳送的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
備註
針對 .NET 5.0.1 和任何其他 5.x 版本,
Router
元件中包含的一個參數為PreferExactMatches
,此參數已設定為@true
。 如需詳細資訊,請參閱 從 ASP.NET Core 3.1 移轉至 .NET 5。將具有下列內容的
_Host
檢視新增至專案。Views/Home/_Host.cshtml
:@{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
元件會使用共用的
_Layout.cshtml
檔案進行其配置。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
將動作新增至 Home 控制器。
Controllers/HomeController.cs
:public IActionResult Blazor() { return View("_Host"); }
在
Startup.Configure
的Startup.cs
端點中,為傳回_Host
檢視的控制器動作新增低優先順序路由:endpoints.MapFallbackToController("Blazor", "Home");
下列範例顯示一般應用程式端點設定中新增的行:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapBlazorHub(); endpoints.MapFallbackToController("Blazor", "Home"); });
將可路由傳送的元件新增至專案。
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視渲染元件
本節涉及向頁面或視圖添加元件,此類元件無法由用戶請求直接路由。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
渲染有狀態的互動式元件
有狀態的互動式元件可以添加至 Razor 頁面或檢視。
當頁面或檢視渲染時:
- 元件會與頁面或視圖一起預渲染。
- 用於預先轉譯的初始元件狀態會遺失。
- 在建立 SignalR 連線時會隨即建立新的元件狀態。
以下 Razor 頁面會渲染 Counter
元件:
<h1>My Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
渲染非互動式元件
在下列 Razor 頁面中,Counter
元件會使用表單指定的初始值靜態渲染。 由於元件以靜態方式轉譯,因此元件不具互動性:
<h1>My Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
元件命名空間
在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml
檔案中。 在以下範例中:
- 元件會儲存在專案的
Components
資料夾中。 -
{APP NAMESPACE}
預留位置表示專案的命名空間。Components
代表資料夾的名稱。
@using {APP NAMESPACE}.Components
_ViewImports.cshtml
檔案位於 Pages
Pages 應用程式的 Razor 資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。
預渲染狀態大小和SignalR訊息大小限制
大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:
- SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
- 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。
若要解決該問題,請使用下列任一種方法:
- 減少放入預渲染狀態的資料量。
- 新增 SignalR 訊息大小限制。 警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。
其他 Blazor Server 資源
Razor 元件可以整合到 Razor Pages 或 MVC 應用程式中。 轉譯頁面或檢視時,可以同時預先轉譯元件。
預先轉譯可藉由轉譯初始 HTTP 回應的內容來改善搜尋引擎最佳化 (SEO),讓搜尋引擎可使用該回應來計算頁面排名。
設定專案之後,請根據專案的需求使用以下幾節中的指引:
- 可路由的元件:指可以直接從使用者要求進行路由的元件。 請遵循本指南,以便訪客能夠在瀏覽器中為具有
@page
指令的元件發送 HTTP 請求。 - 從頁面或視圖中渲染元件:適用於使用者請求中無法直接路由的元件。 當應用程式使用元件標籤協助程式將元件內嵌至現有的頁面或檢視時,請遵循此指引。
組態
現有的 Razor Pages 或 MVC 應用程式可以將元件整合到 Razor 頁面或檢視中:
在專案的配置檔案中:
將下列
<base>
標籤新增至<head>
(Pages/Shared/_Layout.cshtml
Pages) 或 Razor (MVC) 中的Views/Shared/_Layout.cshtml
元素:+ <base href="~/" />
上述範例中的
href
值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/
) 中。 如果應用程式是子應用程式,請參閱 ASP.NET Core Blazor 應用程式基底路徑。在
<script>
轉譯區段前面新增blazor.server.js
的Scripts
指令碼標籤。Pages/Shared/_Layout.cshtml
(Razor 頁面) 或Views/Shared/_Layout.cshtml
(MVC):... <script src="_framework/blazor.server.js"></script> @await RenderSectionAsync("Scripts", required: false) </body>
架構會將
blazor.server.js
指令碼新增至應用程式。 無須手動將blazor.server.js
指令碼檔案新增至應用程式。
將具有下列內容的匯入檔案新增至專案的根資料夾。 將
{APP NAMESPACE}
預留位置變更為專案的命名空間。_Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.JSInterop @using {APP NAMESPACE}
在 Blazor Server 中註冊
Startup.ConfigureServices
服務。Startup.cs
:services.AddServerSideBlazor();
將 Blazor 中樞端點新增到
app.UseEndpoints
的端點清單中 (Startup.Configure
)。Startup.cs
:endpoints.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor 頁面) 或Views/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Pages:
在專案的
Index
Pages 應用程式 Razor 頁面中,新增Counter
元件的命名空間,並將元件內嵌至頁面中。 當Index
頁面載入時,Counter
元件會被預渲染在頁面中。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Pages/Index.cshtml
:@page @using {APP NAMESPACE}.Pages.Shared @model IndexModel @{ ViewData["Title"] = "Home page"; } <div> <component type="typeof(Counter)" render-mode="ServerPrerendered" /> </div>
在上述範例中,將
{APP NAMESPACE}
預留位置取代為應用程式的命名空間。MVC:
在專案的 MVC 應用程式
Index
檢視中,新增Counter
元件的命名空間,並將元件內嵌至檢視中。 當Index
檢視載入時,Counter
元件會預先在頁面中渲染。 在下列範例中,將{APP NAMESPACE}
預留位置以專案的命名空間取代。Views/Home/Index.cshtml
:@using {APP NAMESPACE}.Views.Shared @{ ViewData["Title"] = "Home Page"; } <div> <component type="typeof(Counter)" render-mode="ServerPrerendered" /> </div>
如需詳細資訊,請參閱從頁面或檢視轉譯元件一節。
在 Razor Pages 應用程式中使用可路由的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 Razor Pages 應用程式中支援可路由的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
將具有下列內容的
_Host
頁面新增至專案。Pages/_Host.cshtml
:@page "/blazor" @{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
元件會使用共用的
_Layout.cshtml
檔案進行其配置。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
在
Startup.Configure
的Startup.cs
端點中,將_Host
頁面的低優先順序路由新增為最後一個端點:endpoints.MapFallbackToPage("/_Host");
下列範例顯示一般應用程式端點設定中新增的行:
app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
將可路由傳送的元件新增至專案。
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 MVC 應用程式中使用可路由傳送的元件
本節涉及新增可直接從使用者要求路由的元件。
若要在 MVC 應用程式中支援可路由傳送的 Razor 元件:
將具有下列內容的
App
元件新增至專案根目錄。App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
將具有下列內容的
_Host
檢視新增至專案。Views/Home/_Host.cshtml
:@{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
元件會使用共用的
_Layout.cshtml
檔案進行其配置。RenderMode 配置是否使用
App
組件。- 被預渲染到頁面中。
- 是否在頁面上呈現為靜態 HTML,或包含從使用者代理啟動 Blazor 應用程式所需的資訊。
如需元件標籤協助程式的詳細資訊 (包括傳遞參數和 RenderMode 設定),請參閱 ASP.NET Core 中的元件標籤協助程式。
將動作新增至 Home 控制器。
Controllers/HomeController.cs
:public IActionResult Blazor() { return View("_Host"); }
在
Startup.Configure
的Startup.cs
端點中,為傳回_Host
檢視的控制器動作新增低優先順序路由:endpoints.MapFallbackToController("Blazor", "Home");
下列範例顯示一般應用程式端點設定中新增的行:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapBlazorHub(); endpoints.MapFallbackToController("Blazor", "Home"); });
將可路由傳送的元件新增至專案。
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
執行專案並前往位於
RoutableCounter
的可路由/routable-counter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視渲染元件
本節涉及向頁面或視圖添加元件,此類元件無法由用戶請求直接路由。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
渲染有狀態的互動式元件
有狀態的互動式元件可以添加至 Razor 頁面或檢視。
當頁面或檢視渲染時:
- 元件會與頁面或視圖一起預渲染。
- 用於預先轉譯的初始元件狀態會遺失。
- 在建立 SignalR 連線時會隨即建立新的元件狀態。
以下 Razor 頁面會渲染 Counter
元件:
<h1>My Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
渲染非互動式元件
在下列 Razor 頁面中,Counter
元件會使用表單指定的初始值靜態渲染。 由於元件以靜態方式轉譯,因此元件不具互動性:
<h1>My Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
如需詳細資訊,請參閱 ASP.NET Core 中的元件標籤協助程式。
元件命名空間
在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml
檔案中。 在以下範例中:
- 元件會儲存在專案的
Components
資料夾中。 -
{APP NAMESPACE}
預留位置表示專案的命名空間。Components
代表資料夾的名稱。
@using {APP NAMESPACE}.Components
_ViewImports.cshtml
檔案位於 Pages
Pages 應用程式的 Razor 資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。
預渲染狀態大小和SignalR訊息大小限制
大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:
- SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
- 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。
若要解決該問題,請使用下列任一種方法:
- 減少放入預渲染狀態的資料量。
- 新增 SignalR 訊息大小限制。 警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。