將 ASP.NET Core Razor 元件整合至 ASP.NET Core 應用程式中
本文說明 ASP.NET Core 應用程式的 Razor 元件整合案例。
Razor 元件整合
Razor 元件可以整合到 Razor Pages、MVC 和其他類型的 ASP.NET Core 應用程式。 Razor 元件也可以整合到任何 Web 應用程式中,包括不是以 ASP.NET Core 為基礎的應用程式,作為自訂 HTML 元素。
根據應用程式的需求,使用下列各節中的指導:
- 若要整合無法直接從使用者要求路由的元件,請遵循 使用在頁面或檢視中非路由元件 一節中的指導。 當應用程式使用元件標記協助程式將元件內嵌至現有頁面和檢視時,請遵循此指導。
- 若要整合元件與完整 Blazor 支援,請遵循 新增 Blazor 支援至 ASP.NET Core 應用程式 一節中的指導。
使用在頁面或檢視中不可路由傳送的元件
使用下列指導,藉由 元件標記協助程式整合 Razor 元件至現有 Razor 頁面或 MVC 應用程式中。
注意
如果您的應用程式需要直接可路由元件(未內嵌至頁面或檢視),請略過本節,並使用 新增 Blazor 支援至 ASP.NET Core 應用程式 一節中的指導。
使用伺服器預先轉譯且頁面或檢視轉譯時:
- 元件會與頁面或檢視一起預先轉譯。
- 用於預先轉譯的初始元件狀態會遺失。
- 在建立 SignalR 連線時會隨即建立新的元件狀態。
如需轉譯模式的詳細資訊 (包括非互動式靜態元件轉譯),請參閱 ASP.NET Core 中的元件標記協助程式。 若要儲存預先轉譯 Razor 元件的狀態,請參閱在 ASP.NET Core 中保存元件狀態標記協助程式。
將 Components
資料夾新增至專案的根資料夾。
將匯入檔案新增至具有下列內容的 Components
資料夾。 將 {APP NAMESPACE}
預留位置變更為專案的命名空間。
Components/_Imports.razor
:
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components
在專案的配置檔案 (在 Razor Pages 應用程式中的 Pages/Shared/_Layout.cshtml
或 MVC 應用程式中的 Views/Shared/_Layout.cshtml
) 中:
將 HeadOutlet 元件的下列
<base>
標記和元件標記協助程式新增至<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.web.js
指令碼的<script>
標記:<script src="_framework/blazor.web.js"></script>
Blazor 架構會自動將
blazor.web.js
指令碼新增至應用程式。
注意
通常配置會透過 _ViewStart.cshtml
檔案載入。
將非操作 (no-op) App
元件新增至專案。
Components/App.razor
:
@* No-op App component *@
在註冊服務的位置上新增 Razor 元件和服務的服務,以支援轉譯互動式伺服器元件。
在 Program
檔案頂端,將 using
陳述式新增至專案元件的檔案頂端:
using {APP NAMESPACE}.Components;
在上述行中,將 {APP NAMESPACE}
預留位置變更為應用程式的命名空間。 例如:
using BlazorSample.Components;
在建置應用程式 (builder.Build()
) 行前的 Program
檔案中:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
如需新增互動式伺服器和 WebAssembly 元件支援的詳細資訊,請參閱 ASP.NET Core Blazor 轉譯模式。
緊接在呼叫以對應 Razor Pages 應用程式中的 Razor Pages (MapRazorPages) 或對應 MVC 應用程式中預設控制器路由 (MapControllerRoute) 的 Program
檔案中,呼叫 MapRazorComponents 以探索可用元件並指定應用程式的根元件 (載入的第一個元件)。 根據預設,應用程式的根元件是 App
元件 (App.razor
)。 鏈結對 AddInteractiveServerRenderMode 的呼叫以設定應用程式的互動式伺服器端轉譯 (互動式 SSR):
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
將元件整合至任何頁面或檢視中。 例如,將 EmbeddedCounter
元件新增至專案的 Components
資料夾。
Components/EmbeddedCounter.razor
:
<h1>Embedded 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
頁面中,新增 EmbeddedCounter
元件的命名空間,並將元件內嵌至頁面中。 當 Index
頁面載入時,系統會在頁面中轉譯 EmbeddedCounter
元件。 在下列範例中,將 {APP NAMESPACE}
預留位置以專案的命名空間取代。
Pages/Index.cshtml
:
@page
@using {APP NAMESPACE}.Components
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<component type="typeof(EmbeddedCounter)" render-mode="ServerPrerendered" />
MVC:
在專案的 MVC 應用程式 Index
檢視中,新增 EmbeddedCounter
元件的命名空間,並將元件內嵌至檢視中。 當 Index
檢視載入時,系統會在頁面中轉譯 EmbeddedCounter
元件。 在下列範例中,將 {APP NAMESPACE}
預留位置以專案的命名空間取代。
Views/Home/Index.cshtml
:
@using {APP NAMESPACE}.Components
@{
ViewData["Title"] = "Home Page";
}
<component type="typeof(EmbeddedCounter)" render-mode="ServerPrerendered" />
將 Blazor 支援新增至 ASP.NET Core 應用程式
本節說明如何將 Blazor 支援新增至 ASP.NET Core 應用程式:
注意
在本節中的範例中,範例應用程式的名稱和命名空間為 BlazorSample
。
新增靜態伺服器端轉譯 (靜態SSR)
將 Components
資料夾新增至應用程式。
針對 Razor 元件所使用的命名空間,新增下列 _Imports
檔案。
Components/_Imports.razor
:
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using {APP NAMESPACE}
@using {APP NAMESPACE}.Components
將命名空間預留位置 ({APP NAMESPACE}
) 變更為應用程式的命名空間。 例如:
@using BlazorSample
@using BlazorSample.Components
將 Blazor 路由器 (<Router>
、Router) 新增至 Routes
元件中的應用程式,該元件放在應用程式的 Components
資料夾中。
Components/Routes.razor
:
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>
將 App
元件新增至應用程式作為根元件,這是應用程式載入的第一個元件。
Components/App.razor
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="@Assets["{ASSEMBLY NAME}.styles.css"]" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="{ASSEMBLY NAME}.styles.css" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
預留位置 {ASSEMBLY NAME}
是應用程式的組件名稱。 例如,具有組件名稱 ContosoApp
的專案會使用 ContosoApp.styles.css
樣式表檔名。
將 Pages
資料夾新增至 Components
資料夾,以保存可路由的 Razor 元件。
新增下列 Welcome
元件來示範靜態 SSR。
Components/Pages/Welcome.razor
:
@page "/welcome"
<PageTitle>Welcome!</PageTitle>
<h1>Welcome to Blazor!</h1>
<p>@message</p>
@code {
private string message =
"Hello from a Razor component and welcome to Blazor!";
}
在 ASP.NET Core 專案的 Program
檔案中:
將
using
陳述式新增至專案元件的檔案頂端:using {APP NAMESPACE}.Components;
在上述行中,將
{APP NAMESPACE}
預留位置變更為應用程式的命名空間。 例如:using BlazorSample.Components;
新增 Razor 元件服務 (AddRazorComponents),這也會自動新增防偽服務 (AddAntiforgery)。 在呼叫
builder.Build()
的行前面新增下列這一行:builder.Services.AddRazorComponents();
將防偽中介軟體與 UseAntiforgery 一起新增至要求處理管線。 在呼叫 UseRouting 之後呼叫 UseAntiforgery。 如果有對 UseRouting 和 UseEndpoints 發出呼叫,則對 UseAntiforgery 的呼叫必須介於這兩者之間。 對 UseAntiforgery 發出的呼叫必須在放置對 UseAuthentication 和 UseAuthorization 發出的呼叫之後。
app.UseAntiforgery();
將 MapRazorComponents 新增至應用程式的要求處理管線,並將
App
元件 (App.razor
) 指定為預設根元件 (載入的第一個元件)。 將下列程式碼放在呼叫app.Run
的行前面:app.MapRazorComponents<App>();
執行應用程式時,Welcome
元件會在 /welcome
端點上存取。
啟用互動式伺服器端轉譯 (互動式 SSR)
請遵循新增靜態伺服器端轉譯 (靜態 SSR) 一節中的指導。
在應用程式的 Program
檔案中,新增對 AddInteractiveServerComponents 的呼叫,其中 Razor 元件服務會透過 AddRazorComponents 新增:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
新增對 AddInteractiveServerRenderMode 的呼叫,其中 Razor 元件會透過 MapRazorComponents 來對應:
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
將下列 Counter
元件新增至採用互動式伺服器端轉譯 (互動式 SSR) 的應用程式。
Components/Pages/Counter.razor
:
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
執行應用程式時,會在 /counter
存取 Counter
元件。
啟用互動式自動 (自動) 或用戶端轉譯 (CSR)
請遵循新增靜態伺服器端轉譯 (靜態 SSR) 一節中的指導。
使用互動式自動轉譯模式的元件一開始會使用互動式 SSR。 .NET 執行階段和應用程式套件組合會在背景下載到用戶端並快取,以便在未來造訪時使用。 只有在下載 Blazor 套件組合並啟動 Blazor 執行階段之後,使用互動式 WebAssembly 轉譯模式的元件才會在用戶端上以互動方式轉譯。 請記住,使用互動式自動或互動式 WebAssembly 轉譯模式時,下載至用戶端的元件程式碼不是私人的。 如需詳細資訊,請參閱 ASP.NET Core Blazor 轉譯模式。
決定要採用哪個轉譯模式之後:
- 如果您打算採用互動式自動轉譯模式,請遵循啟用互動式伺服器端轉譯 (互動式 SSR) 一節中的指導。
- 如果您打算只採用互動式 WebAssembly 轉譯,請繼續執行,而不新增互動式 SSR。
將 Microsoft.AspNetCore.Components.WebAssembly.Server
NuGet 套件的套件參考新增至應用程式。
注意
如需將套件新增至 .NET 應用程式的指引,請參閱在套件取用工作流程 (NuGet 文件) 的安裝及管理套件底下的文章。 在 NuGet.org 確認正確的套件版本。
建立捐贈者 Blazor Web App 應用程式,將資產提供給應用程式。 請遵循 ASP.NET Core 的工具Blazor 一文中的指引,在產生 Blazor Web App 時選取支援下列範本功能。
針對應用程式的名稱,使用與 ASP.NET Core 應用程式相同的名稱,這會導致在元件中比對應用程式名稱標記以及在程式碼中比對命名空間。 不嚴格要求使用相同的名稱/命名空間,因為在資產從捐贈者應用程式移至 ASP.NET Core 應用程式之後,即可調整命名空間。 不過,一開始比對命名空間可節省時間。
Visual Studio:
- 針對 [互動式轉譯模式],選取 [自動 (伺服器和 WebAssembly)]。
- 將 [互動位置] 設定為 [每一頁/每個元件]。
- 取消選取 [包含範例頁面] 的核取方塊。
.NET CLI:
- 使用
-int Auto
選項。 - 請勿使用
-ai|--all-interactive
選項。 - 傳遞
-e|--empty
選項。
從捐贈者 Blazor Web App,將整個 .Client
專案複製到 ASP.NET Core 應用程式的解決方案資料夾中。
重要
請勿將 .Client
資料夾複製到 ASP.NET Core 專案的資料夾中。 組織 .NET 解決方案的最佳方法是將解決方案的每個專案放在最上層解決方案資料夾內自己的資料夾中。 如果 ASP.NET Core 專案資料夾上方的解決方案資料夾不存在,請加以建立。 接下來,將 .Client
專案的資料夾從捐贈者 Blazor Web App 複製到解決方案資料夾中。 最終專案資料夾結構應該具有下列配置:
BlazorSampleSolution
(最上層解決方案資料夾)BlazorSample
(原始 ASP.NET Core 專案)BlazorSample.Client
(.Client
專案資料夾,來自捐贈者Blazor Web App)
針對 ASP.NET Core 方案檔,您可將它保留在 ASP.NET Core 專案的資料夾中。 或者,只要專案參考正確指向解決方案資料夾中兩個專案的專案檔 (.csproj
),您即可移動方案檔,或在最上層方案資料夾中建立新的方案檔。
如果您在建立捐贈者專案時,將捐贈者 Blazor Web App Web 應用程式命名為與 ASP.NET Core 應用程式相同,則捐贈資產所使用的命名空間會符合 ASP.NET Core 應用程式中的命名空間。 您不應該採取進一步的步驟來比對命名空間。 如果您在建立捐贈者 Blazor Web App專案時使用不同的命名空間,若打算完全依照所呈現的方式 rest 使用本指南的其餘部分,則必須調整要比對之所有捐贈資產的命名空間。 如果命名空間不相符,請在繼續之前先調整命名空間,或者依照本節中的其餘指引來調整命名空間。
刪除捐贈者 Blazor Web App ,因為在此程序中不會進一步使用它。
將 .Client
專案新增至解決方案:
Visual Studio:以滑鼠右鍵按一下 [方案總管] 中的解決方案,然後選取 [新增]>[現有專案]。 瀏覽至
.Client
資料夾,然後選取專案檔 (.csproj
)。.NET CLI:使用
dotnet sln add
命令 將.Client
專案新增至解決方案。
將專案參考從 ASP.NET Core 專案新增至用戶端專案:
Visual Studio:以滑鼠右鍵按一下 ASP.NET Core 專案,然後選取 [新增]>[專案參考]。 選取
.Client
專案,然後選取 [確定]。.NET CLI:從 ASP.NET Core 專案的資料夾,使用下列命令:
dotnet add reference ../BlazorSample.Client/BlazorSample.Client.csproj
上述命令假設下列各項:
- 專案檔名稱為
BlazorSample.Client.csproj
。 .Client
專案位於解決方案資料夾內的BlazorSample.Client
資料夾中。.Client
資料夾與 ASP.NET Core 專案的資料夾並存。
如需
dotnet add reference
命令的詳細資訊,請參閱dotnet add reference
(.NET 文件)。- 專案檔名稱為
對 ASP.NET Core 應用程式的 Program
檔案進行下列變更:
使用 AddInteractiveWebAssemblyComponents 新增互動式 WebAssembly 元件服務,其中 Razor 元件服務會使用 AddRazorComponents 來新增。
針對互動式自動轉譯:
builder.Services.AddRazorComponents() .AddInteractiveServerComponents() .AddInteractiveWebAssemblyComponents();
僅針對互動式 WebAssembly 轉譯:
builder.Services.AddRazorComponents() .AddInteractiveWebAssemblyComponents();
為
.Client
專案新增互動式 WebAssembly 轉譯模式 (AddInteractiveWebAssemblyRenderMode) 和其他組件,其中 Razor 元件會與 MapRazorComponents 對應。針對互動式自動 (自動) 轉譯:
app.MapRazorComponents<App>() .AddInteractiveServerRenderMode() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
僅針對互動式 WebAssembly 轉譯:
app.MapRazorComponents<App>() .AddInteractiveWebAssemblyRenderMode() .AddAdditionalAssemblies(typeof(BlazorSample.Client._Imports).Assembly);
在上述範例中,變更
BlazorSample.Client
以符合.Client
專案的命名空間。
將 Pages
資料夾新增至 .Client
專案。
如果 ASP.NET Core 專案有現有的 Counter
元件:
- 將元件移至
.Client
專案的Pages
資料夾。 - 移除元件檔案頂端的
@rendermode
指示詞。
如果 ASP.NET Core 應用程式沒有 Counter
元件,請將下列 Counter
元件 (Pages/Counter.razor
) 新增至 .Client
專案:
@page "/counter"
@rendermode InteractiveAuto
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
如果應用程式只採用互動式 WebAssembly 轉譯,請移除 @rendermode
指示詞和值:
- @rendermode InteractiveAuto
從 ASP.NET Core 應用程式 專案執行解決方案:
Visual Studio:確認在執行應用程式時,已在 [方案總管] 中選取 ASP.NET Core 專案。
.NET CLI:從 ASP.NET Core 專案的資料夾執行專案。
若要載入 Counter
元件,請瀏覽至 /counter
。
實作 Blazor的版面配置和樣式
或者,使用 RouteView
元件的 RouteView.DefaultLayout 參數來指派預設版面配置元件。
在 Routes.razor
,下列範例會使用 MainLayout
元件作為預設版面配置:
<RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />
如需詳細資訊,請參閱 ASP.NET Core Blazor 配置。
Blazor 專案範本版面配置和樣式表單可從 dotnet/aspnetcore
GitHub 存放庫取得:
MainLayout.razor
MainLayout.razor.css
NavMenu.razor
NavMenu.razor.css
注意
.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤。
根據您在應用程式組織版面配置檔案的方式,您可能需要在應用程式的 _Imports.razor
檔案中新增 @using
版面配置檔案資料夾的語句,才能呈現這些檔案以用於應用程式的元件。
使用 CSS 隔離時,不需要明確參考樣式表單。 架構 Blazor 會自動組合個別元件樣式表單。 應用程式的組合樣式表單已在應用程式的 App
元件中參考({ASSEMBLY NAME}.styles.css
其中 {ASSEMBLY NAME}
預留位置是應用程式的組件名稱)。
從 MVC 控制器動作傳回 RazorComponentResult
MVC 控制器動作可傳回具有 RazorComponentResult<TComponent> 的元件。
Components/Welcome.razor
:
<PageTitle>Welcome!</PageTitle>
<h1>Welcome!</h1>
<p>@Message</p>
@code {
[Parameter]
public string? Message { get; set; }
}
在控制器中:
public IResult GetWelcomeComponent() =>
new RazorComponentResult<Welcome>(new { Message = "Hello, world!" });
只會傳回轉譯元件的 HTML 標記。 配置和 HTML 頁面標記不會隨著元件自動轉譯。 為了產生完整 HTML 頁面,應用程式可以維護 Blazor 配置,為 <html>
、<head>
、<body>
和其他標籤提供 HTML 標記。 元件包含在元件定義檔案頂端具有 @layout
Razor 指示詞的配置,在本節中的範例為 Welcome.razor
。 下列範例假設應用程式具有名為 RazorComponentResultLayout
(Components/Layout/RazorComponentResultLayout.razor
) 的配置:
@using BlazorSample.Components.Layout
@layout RazorComponentResultLayout
您可以藉由將其移至應用程式的 _Imports.razor
檔案,避免在個別元件中針對 Layout
資料夾放置 @using
陳述式。
如需詳細資訊,請參閱 ASP.NET Core Blazor 配置。
元件命名空間
在使用自訂資料夾來保存專案的 Razor 元件時,請將代表資料夾的命名空間新增至頁面/檢視或 _ViewImports.cshtml
檔案中。 在以下範例中:
- 元件會儲存在專案的
Components
資料夾中。 {APP NAMESPACE}
預留位置是專案的命名空間。Components
代表資料夾的名稱。
@using {APP NAMESPACE}.Components
例如:
@using BlazorSample.Components
_ViewImports.cshtml
檔案位於 Razor Pages 應用程式的 Pages
資料夾或 MVC 應用程式的 Views
資料夾中。
如需詳細資訊,請參閱 ASP.NET Core Razor 元件。