整合 ASP.NET Core Razor 元件與MVC或 Razor Pages
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .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}
在專案的配置檔案 (在 Razor Pages 應用程式中的
Pages/Shared/_Layout.cshtml
或 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 元件是用來轉譯頁面標題 (PageTitle 元件) 和其他由 Razor 元件所設定之標題元素 (HeadContent 元件) 的標題 (
<head>
) 內容。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。在
Scripts
轉譯區段 (@await RenderSectionAsync(...)
) 之前立即新增blazor.server.js
指令碼的<script>
標記:<script src="_framework/blazor.server.js"></script>
架構會將
blazor.server.js
指令碼新增至應用程式。 無須手動將blazor.server.js
指令碼檔案新增至應用程式。
注意
通常配置會透過
_ViewStart.cshtml
檔案載入。在註冊服務的
Program.cs
中註冊 Blazor Server 服務:builder.Services.AddServerSideBlazor();
將 Blazor 中樞端點新增至對應路由的
Program.cs
的端點。 在MapRazorPages
(Razor Pages) 或MapControllerRoute
(MVC) 的呼叫後面放置以下這一行:app.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor Pages) 或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:
在專案的 Razor Pages 應用程式
Index
頁面中,新增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");
將可路由傳送的元件新增至專案。 下列範例是以 Blazor 專案範本中
Counter
元件為基礎的RoutableCounter
元件。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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 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
資料夾,並新增可路由傳送的元件。 下列範例是以 Blazor 專案範本中Counter
元件為基礎的RoutableCounter
元件。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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視轉譯元件
本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
轉譯具狀態互動式元件
具狀態互動式元件可以新增至 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
檔案位於 Razor Pages 應用程式的 Pages
資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。
保存預先轉譯的狀態
若未保存預先轉譯的狀態,在預先轉譯期間所使用的狀態會遺失,而且必須在應用程式完全載入時重建。 如果以非同步方式設定了任何狀態,UI 可能會閃動,因為預先轉譯的 UI 會取代為暫時的預留位置,然後再次完整轉譯。
若要保存預先轉譯元件的狀態,請使用保存元件狀態標記協助程式 (參考來源)。 在預先轉譯元件的應用程式中 _Host
頁面的結尾 </body>
標記內,新增標記協助程式的標記 <persist-component-state />
。
注意
.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤。
Blazor在Pages/_Host.cshtml
應用程式中ServerPrerendered
Blazor Server的應用程式:
<body>
...
<persist-component-state />
</body>
使用 PersistentComponentState 服務決定要保存哪個狀態。 PersistentComponentState.RegisterOnPersisting
會註冊回呼,以在應用程式暫停前保存元件狀態。 應用程式繼續時會擷取此狀態。
在以下範例中:
{TYPE}
預留位置代表要保存的資料類型 (例如WeatherForecast[]
)。{TOKEN}
預留位置是狀態識別碼字串 (例如fetchdata
)。
@implements IDisposable
@inject PersistentComponentState ApplicationState
...
@code {
private {TYPE} data;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
persistingSubscription =
ApplicationState.RegisterOnPersisting(PersistData);
if (!ApplicationState.TryTakeFromJson<{TYPE}>(
"{TOKEN}", out var restored))
{
data = await ...;
}
else
{
data = restored!;
}
}
private Task PersistData()
{
ApplicationState.PersistAsJson("{TOKEN}", data);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
下列範例是以專案範本為基礎的Blazor元件更新版本FetchData
。 WeatherForecastPreserveState
元件會在預先轉譯期間保存氣象預報狀態,然後擷取該狀態以初始化元件。 保存元件狀態標籤協助程式會在所有元件叫用之後保存元件狀態。
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()
{
persistingSubscription =
ApplicationState.RegisterOnPersisting(PersistForecasts);
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
"fetchdata", out var restored))
{
forecasts =
await WeatherForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
}
else
{
forecasts = restored!;
}
}
private Task PersistForecasts()
{
ApplicationState.PersistAsJson("fetchdata", 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 元件標籤協助程式新增至Pages/Shared/_Layout.cshtml
(Razor Pages) 或Views/Shared/_Layout.cshtml
(MVC) 中的<head>
元素:<base href="~/" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
上述範例中的
href
值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/
) 中。 如果應用程式是子應用程式,請遵循裝載及部署 ASP.NET Core Blazor (部分機器翻譯) 文章之應用程式基本路徑一節中的指導。HeadOutlet 元件是用來轉譯頁面標題 (PageTitle 元件) 和其他由 Razor 元件所設定之標題元素 (HeadContent 元件) 的標題 (
<head>
) 內容。 如需詳細資訊,請參閱在 ASP.NET Core Blazor 應用程式中控制標題內容 (部分機器翻譯)。在應用程式的配置中,在
Scripts
轉譯區段 (@await RenderSectionAsync(...)
) 前面新增blazor.server.js
指令碼的<script>
標籤。Pages/Shared/_Layout.cshtml
(Razor Pages) 或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}
在註冊服務的
Program.cs
中註冊 Blazor Server 服務:builder.Services.AddServerSideBlazor();
將 Blazor 中樞端點新增至對應路由的
Program.cs
的端點。在
MapRazorPages
(Razor Pages) 或MapControllerRoute
(MVC) 的呼叫後面放置以下這一行:app.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor Pages) 或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:
在專案的 Razor Pages 應用程式
Index
頁面中,新增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");
將可路由傳送的元件新增至專案。 下列範例是以 Blazor 專案範本中
Counter
元件為基礎的RoutableCounter
元件。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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 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
資料夾,並新增可路由傳送的元件。 下列範例是以 Blazor 專案範本中Counter
元件為基礎的RoutableCounter
元件。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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視轉譯元件
本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
轉譯具狀態互動式元件
具狀態互動式元件可以新增至 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
檔案位於 Razor Pages 應用程式的 Pages
資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。
保存預先轉譯的狀態
若未保存預先轉譯的狀態,在預先轉譯期間所使用的狀態會遺失,而且必須在應用程式完全載入時重建。 如果以非同步方式設定了任何狀態,UI 可能會閃動,因為預先轉譯的 UI 會取代為暫時的預留位置,然後再次完整轉譯。
為了解決這些問題,Blazor 支援使用保存元件狀態標籤協助程式在預先轉譯的頁面中保存狀態。 在結尾 </body>
標籤內新增標籤協助程式的標籤 <persist-component-state />
。
Pages/_Layout.cshtml
:
<body>
...
<persist-component-state />
</body>
使用 PersistentComponentState 服務決定要保存哪個狀態。 PersistentComponentState.RegisterOnPersisting
會註冊回呼,以在應用程式暫停前保存元件狀態。 應用程式繼續時會擷取此狀態。
下列範例是以專案範本為基礎的Blazor元件更新版本FetchData
。 WeatherForecastPreserveState
元件會在預先轉譯期間保存氣象預報狀態,然後擷取該狀態以初始化元件。 保存元件狀態標籤協助程式會在所有元件叫用之後保存元件狀態。
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()
{
persistingSubscription =
ApplicationState.RegisterOnPersisting(PersistForecasts);
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
"fetchdata", out var restored))
{
forecasts =
await WeatherForecastService.GetForecastAsync(DateTime.Now);
}
else
{
forecasts = restored!;
}
}
private Task PersistForecasts()
{
ApplicationState.PersistAsJson("fetchdata", 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>
標籤新增至Pages/Shared/_Layout.cshtml
(Razor Pages) 或Views/Shared/_Layout.cshtml
(MVC) 中的<head>
元素:<base href="~/" />
上述範例中的
href
值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/
) 中。 如果應用程式是子應用程式,請遵循裝載及部署 ASP.NET Core Blazor (部分機器翻譯) 文章之應用程式基本路徑一節中的指導。在
Scripts
轉譯區段前面新增blazor.server.js
指令碼的<script>
標籤。Pages/Shared/_Layout.cshtml
(Razor Pages) 或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}
在
Startup.ConfigureServices
中註冊 Blazor Server 服務。在
Startup.cs
中:services.AddServerSideBlazor();
將 Blazor 中樞端點新增至
Startup.Configure
的端點 (app.UseEndpoints
)。Startup.cs
:endpoints.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor Pages) 或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:
在專案的 Razor Pages 應用程式
Index
頁面中,新增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>
注意
隨著 ASP.NET Core 5.0.1 的發行以及在任何其他 5.x 版中,
Router
元件會包含設定為@true
的PreferExactMatches
參數。 如需詳細資訊,請參閱從 ASP.NET Core 3.1 移轉至 5.0。將具有下列內容的
_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.cs
的Startup.Configure
端點中,將_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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 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>
注意
隨著 ASP.NET Core 5.0.1 的發行以及在任何其他 5.x 版中,
Router
元件會包含設定為@true
的PreferExactMatches
參數。 如需詳細資訊,請參閱從 ASP.NET Core 3.1 移轉至 5.0。將具有下列內容的
_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.cs
的Startup.Configure
端點中,為傳回_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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視轉譯元件
本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
轉譯具狀態互動式元件
具狀態互動式元件可以新增至 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
檔案位於 Razor Pages 應用程式的 Pages
資料夾或 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>
標籤新增至Pages/Shared/_Layout.cshtml
(Razor Pages) 或Views/Shared/_Layout.cshtml
(MVC) 中的<head>
元素:+ <base href="~/" />
上述範例中的
href
值 ( 應用程式基本路徑) 假設應用程式位於根 URL 路徑 (/
) 中。 如果應用程式是子應用程式,請遵循裝載及部署 ASP.NET Core Blazor (部分機器翻譯) 文章之應用程式基本路徑一節中的指導。在
Scripts
轉譯區段前面新增blazor.server.js
指令碼的<script>
標籤。Pages/Shared/_Layout.cshtml
(Razor Pages) 或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}
在
Startup.ConfigureServices
中註冊 Blazor Server 服務。Startup.cs
:services.AddServerSideBlazor();
將 Blazor 中樞端點新增至
Startup.Configure
的端點 (app.UseEndpoints
)。Startup.cs
:endpoints.MapBlazorHub();
將元件整合至任何頁面或檢視中。 例如,將
Counter
元件新增至專案的Shared
資料夾。Pages/Shared/Counter.razor
(Razor Pages) 或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:
在專案的 Razor Pages 應用程式
Index
頁面中,新增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.cs
的Startup.Configure
端點中,將_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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
在 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.cs
的Startup.Configure
端點中,為傳回_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++; } }
執行專案並瀏覽至位於
/routable-counter
之可路由傳送的RoutableCounter
元件。
如需命名空間的詳細資訊,請參閱元件命名空間一節。
從頁面或檢視轉譯元件
本節說明在無法直接從使用者要求路由傳送元件的情況下,如何將元件新增至頁面或檢視。
若要從頁面或檢視轉譯元件,請使用元件標籤協助程式。
轉譯具狀態互動式元件
具狀態互動式元件可以新增至 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
檔案位於 Razor Pages 應用程式的 Pages
資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。
預先轉譯狀態大小和 SignalR 訊息大小限制
大型預先呈現的狀態大小可能超過 Blazor線路 SignalR 訊息大小限制,這會導致下列結果:
- SignalR 線路無法初始化,且用戶端發生錯誤:Circuit host not initialized.
- 當線路發生中斷時,用戶端會出現重新連線的 UI。 不可能復原。
若要解決該問題,請使用下列任一種方法:
- 減少放入預先轉譯狀態的資料量。
- 新增 SignalR 訊息大小限制。 警告:增加限制可能會增加拒絕服務 (DoS) 攻擊的風險。