将 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 组件)的头 (
<head>
) 内容和由 Razor 组件设置的其他头元素(HeadContent 组件)。 有关详细信息,请参阅在 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
(RazorPages) 或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");
将可路由组件添加到项目。 以下示例是
RoutableCounter
组件,它基于 Blazor 项目模板中的Counter
组件。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
文件夹,并添加可路由的组件。 以下示例是RoutableCounter
组件,它基于 Blazor 项目模板中的Counter
组件。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 核心数据保护 可确保在应用中安全地 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 组件)的头 (
<head>
) 内容和由 Razor 组件设置的其他头元素(HeadContent 组件)。 有关详细信息,请参阅在 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
(RazorPages) 或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");
将可路由组件添加到项目。 以下示例是
RoutableCounter
组件,它基于 Blazor 项目模板中的Counter
组件。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
文件夹,并添加可路由的组件。 以下示例是RoutableCounter
组件,它基于 Blazor 项目模板中的Counter
组件。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 核心数据保护 可确保在应用中安全地 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
组件包含PreferExactMatches
参数(设置为@true
)。 有关详细信息,请参阅从 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
组件包含PreferExactMatches
参数(设置为@true
)。 有关详细信息,请参阅从 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) 攻击风险。