将 ASP.NET Core Razor 组件集成到 ASP.NET Core 应用

本文介绍 ASP.NET Core 应用的 Razor 组件集成方案。

Razor 组件集成

Razor 组件可以集成到 Razor 页面、MVC 和其他类型的 ASP.NET Core 应用中。 Razor 组件还可以作为自定义 HTML 元素集成到任何 Web 应用,包括不是基于 ASP.NET Core 的应用。

根据项目的要求,使用以下部分中的指南:

将 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>

可以使用 RouteView 组件的 RouteView.DefaultLayout 参数提供默认布局:

<RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" />

有关详细信息,请参阅 ASP.NET Core Blazor 布局

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="BlazorSample.styles.css" />
    <HeadOutlet />
</head>

<body>
    <Routes />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

对于前面的示例中的 <link> 元素,请更改样式表的文件名中的 BlazorSample 以匹配应用的项目名称。 例如,命名为 ContosoApp 的项目使用 ContosoApp.styles.css 样式表文件名:

<link rel="stylesheet" href="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();
    
  • 使用 UseAntiforgeryAntiforgery 中间件添加到请求处理管道。 UseAntiforgery 在调用 UseRouting 之后调用。 如果有对 UseRoutingUseEndpoints 的调用,则对 UseAntiforgery 的调用必须介于两者之间。 对 UseAntiforgery 的调用必须在对 UseAuthenticationUseAuthorization 的调用后发出。

    app.UseAntiforgery();
    
  • 使用指定为默认根组件(即加载的第一个组件)的 App 组件 (App.razor) 将 MapRazorComponents 添加到应用的请求处理管道。 将以下代码置于调用 app.Run 的行前面:

    app.MapRazorComponents<App>();
    

运行应用时,将在 /welcome 终结点处访问 Welcome 组件。

启用交互式服务器端呈现(交互式 SSR)

按照添加静态服务器端呈现(静态 SSR)部分中的指导进行操作。

在应用的 Program 文件中,添加对 AddInteractiveServerComponents 的调用,其中使用 AddRazorComponents 添加了 Razor 组件服务:

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 组件。

启用交互式自动 (Auto) 或客户端呈现 (CSR)

按照添加静态服务器端呈现(静态 SSR)部分中的指导进行操作。

使用交互式自动呈现模式的组件最初使用交互式 SSR。 .NET 运行时和应用捆绑包会在后台下载到客户端并缓存,以便将来访问时可以使用它们。 下载 Blazor 捆绑包并激活 Blazor 运行时后,使用交互式 WebAssembly 呈现模式的组件仅在客户端上以交互方式呈现。 请记住,使用交互式自动或交互式 WebAssembly 呈现模式时,下载到客户端的组件代码不是专用的。 有关详细信息,请参阅 ASP.NET Core Blazor 呈现模式

确定要采用的呈现模式后:

Microsoft.AspNetCore.Components.WebAssembly.Server NuGet 包的包引用添加到应用。

注意

有关将包添加到 .NET 应用的指南,请参阅包使用工作流(NuGet 文档)中“安装和管理包”下的文章。 在 NuGet.org 中确认正确的包版本。

创建捐赠者 Blazor Web 应用以向应用提供资产。 按照 ASP.NET Core 工具Blazor文章中的指南进行操作,在生成 Blazor Web 应用时选择对以下模板功能的支持。

对于应用的名称,请使用与 ASP.NET Core 应用相同的名称,这会导致在组件中匹配应用名称标记,并在代码中匹配命名空间。 不严格要求使用相同的名称/命名空间,因为资产从捐赠者应用移动到 ASP.NET Core 应用后,可以调整命名空间。 但是,一开始就通过匹配命名空间来保存时间。

Visual Studio:

  • 对于交互式呈现模式,请选择“自动(服务器和 WebAssembly)”。
  • 将交互位置设置为“每页/组件”。
  • 取消选择包含示例页面的检查框

.NET CLI:

  • 使用 -int Auto 选项。
  • 不要使用 -ai|--all-interactive 选项。
  • 传递 -e|--empty 选项。

在捐赠者 Blazor Web 应用中,将整个 .Client 项目复制到 ASP.NET Core 应用的解决方案文件夹中。

重要

不要将 .Client 文件夹复制到 ASP.NET Core 项目的文件夹。 组织 .NET 解决方案的最佳方法是将解决方案的每个项目放入顶层解决方案文件夹内的自己的文件夹中。 如果 ASP.NET Core 项目文件夹上方的解决方案文件夹不存在,请创建一个。 接下来,将 .Client 项目的文件夹从捐赠者 Blazor Web 应用复制到解决方案文件夹中。 最终项目文件夹结构应具有以下布局:

  • BlazorSampleSolution (顶级解决方案文件夹)
    • BlazorSample (原始 ASP.NET Core 项目)
    • BlazorSample.Client (来自捐赠者 Blazor Web 应用的 .Client 项目文件夹)

对于 ASP.NET Core 解决方案文件,可以将该文件保留在 ASP.NET Core 项目的文件夹中。 或者,只要项目引用正确指向解决方案文件夹中两个项目的项目文件(.csproj),就可以在顶层解决方案文件夹中移动解决方案文件或创建新文件。

如果在创建捐赠者项目时命名捐赠者 Blazor Web 应用与 ASP.NET Core 应用相同,则捐赠资产使用的命名空间与 ASP.NET Core 应用中的命名空间匹配。 无需采取进一步步骤来匹配命名空间。 如果在创建捐赠者 Blazor Web 应用项目时使用了其他命名空间,则必须调整捐赠资产中的命名空间,以便与你打算完全按照所介绍的本指南的其余部分进行匹配。 如果命名空间不匹配,调整命名空间,然后再继续,按照本部分中的剩余指南调整命名空间。

删除捐赠者 Blazor Web 应用,因为它在此过程中没有进一步的用处。

.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 进行映射。

    对于交互式自动 (Auto) 呈现:

    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

在页面或视图中使用不可路由的组件

使用以下指南通过组件标签帮助程序将 Razor 组件集成到现有的 Razor 页面或 MVC 应用的页面和视图中。

使用服务器预呈现并且页面或视图呈现时:

  • 该组件通过页面或视图预呈现。
  • 用于预呈现的初始组件状态丢失。
  • 建立 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 组件)的头 (<head>) 内容和由 Razor 组件设置的其他头元素(HeadContent 组件)。 有关详细信息,请参阅在 ASP.NET Core Blazor 应用中控制头内容

  • 在紧接着 Scripts 呈现部分 (@await RenderSectionAsync(...)) 的前方为 blazor.web.js 脚本添加 <script> 标记:

    <script src="_framework/blazor.web.js"></script>
    

    无需手动将 blazor.web.js 脚本添加到应用,因为 Blazor 框架会将 blazor.web.js 脚本添加到应用。

注意

通常,布局通过 _ViewStart.cshtml 文件加载。

将非操作(无操作)App 组件添加到项目。

Components/App.razor

@* No-op App component *@

注册服务时,为 Razor 组件和服务添加服务以支持呈现交互式服务器组件。

Program 文件顶部,将 using 语句添加到项目组件的文件顶部:

using {APP NAMESPACE}.Components;

在上面的行中,将 {APP NAMESPACE} 占位符更改为应用的命名空间。 例如:

using BlazorSample.Components;

Program 文件中生成应用的行之前 (builder.Build()):

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

有关添加对交互式服务器和 WebAssembly 组件的支持的详细信息,请参阅 ASP.NET Core Blazor 呈现模式

在 Razor Pages 应用中调用映射 Razor Pages (MapRazorPages) 或在 MVC 应用中映射默认控制器路由 (MapControllerRoute) 后,立即在 Program 文件中调用 MapRazorComponents,以发现可用组件并指定应用的根组件(即加载的第一个组件)。 默认情况下,应用的根组件是 App 组件 (App.razor)。 链接对 AddInteractiveInteractiveServerRenderMode 的调用,为应用配置交互式服务器端呈现(交互式 SSR):

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

注意

如果应用尚未更新以包含 Antiforgery 中间件,请在调用 UseAuthorization 后添加以下行:

app.UseAntiforgery();

将组件集成到任何页面或视图。 例如,将 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" />

可路由组件

使用以下指南将可路由的 Razor 组件集成到现有的 Razor 页面或 MVC 应用。

本部分中的指南假定:

  • 应用的标题为 Blazor Sample
  • 应用的命名空间为 BlazorSample

要支持可路由的 Razor 组件:

Components 文件夹添加到项目的根文件夹。

将具有以下内容的导入文件添加到 Components 文件夹。

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

Layout 文件夹添加到 Components 文件夹。

Layout 文件夹添加页脚组件和样式表。

Components/Layout/Footer.razor

<footer class="border-top footer text-muted">
    <div class="container">
        &copy; 2023 - {APP TITLE} - <a href="/privacy">Privacy</a>
    </div>
</footer>

在前面的标记中,将 {APP TITLE} 占位符设置为应用的标题。 例如:

&copy; 2023 - Blazor Sample - <a href="/privacy">Privacy</a>

Components/Layout/Footer.razor.css

.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

将导航菜单组件添加到 Layout 文件夹。

Components/Layout/NavMenu.razor

<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
    <a class="navbar-brand" href="/">{APP TITLE}</a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
    </button>
    <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
        <ul class="navbar-nav flex-grow-1">
            <li class="nav-item">
                <a class="nav-link text-dark" href="/">Home</a>
            </li>
            <li class="nav-item">
                <a class="nav-link text-dark" href="/privacy">Privacy</a>
            </li>
            <li class="nav-item">
                <a class="nav-link text-dark" href="/counter">Counter</a>
            </li>
        </ul>
    </div>
</div>
</nav>

在前面的标记中,将 {APP TITLE} 占位符设置为应用的标题。 例如:

<a class="navbar-brand" href="/">Blazor Sample</a>

Components/Layout/NavMenu.razor.css

a.navbar-brand {
    white-space: normal;
    text-align: center;
    word-break: break-all;
}

a {
    color: #0077cc;
}

.btn-primary {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
    color: #fff;
    background-color: #1b6ec2;
    border-color: #1861ac;
}

.border-top {
    border-top: 1px solid #e5e5e5;
}

.border-bottom {
    border-bottom: 1px solid #e5e5e5;
}

.box-shadow {
    box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}

button.accept-policy {
    font-size: 1rem;
    line-height: inherit;
}

Layout 文件夹添加主布局组件和样式表。

Components/Layout/MainLayout.razor

@inherits LayoutComponentBase

<header>
    <NavMenu />
</header>

<div class="container">
    <main role="main" class="pb-3">
        @Body
    </main>
</div>

<Footer />

<div id="blazor-error-ui">
    An unhandled error has occurred.
    <a href="" class="reload">Reload</a>
    <a class="dismiss">🗙</a>
</div>

Components/Layout/MainLayout.razor.css

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

    #blazor-error-ui .dismiss {
        cursor: pointer;
        position: absolute;
        right: 0.75rem;
        top: 0.5rem;
    }

将具有以下内容的 Routes 组件添加到 Components 文件夹。

Components/Routes.razor

<Router AppAssembly="typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="routeData" Selector="h1" />
    </Found>
</Router>

将具有以下内容的 App 组件添加到 Components 文件夹。

Components/App.razor

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{APP TITLE}</title>
    <link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" href="/css/site.css" />
    <link rel="stylesheet" href="/{APP NAMESPACE}.styles.css" />
    <HeadOutlet />
</head>
<body>
    <Routes />
    <script src="/lib/jquery/dist/jquery.min.js"></script>
    <script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="/js/site.js"></script>
    <script src="_framework/blazor.web.js"></script>
</body>
</html>

在前面的代码中,更新应用标题和样式表文件名:

  • 对于 <title> 元素中的 {APP TITLE} 占位符,请设置应用的标题。 例如:

    <title>Blazor Sample</title>
    
  • 对于样式表 <link> 元素中的 {APP NAMESPACE} 占位符,请设置应用的命名空间。 例如:

    <link rel="stylesheet" href="/BlazorSample.styles.css" />
    

注册服务时,为 Razor 组件和服务添加服务以支持呈现交互式服务器组件。

Program 文件顶部,将 using 语句添加到项目组件的文件顶部:

using {APP NAMESPACE}.Components;

在上面的行中,将 {APP NAMESPACE} 占位符更改为应用的命名空间。 例如:

using BlazorSample.Components;

Program 文件中生成应用的行之前 (builder.Build()):

builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

有关添加对交互式服务器和 WebAssembly 组件的支持的详细信息,请参阅 ASP.NET Core Blazor 呈现模式

Program 文件中紧跟着对映射 Razor 页面 (MapRazorPages) 的调用,调用 MapRazorComponents 以发现可用组件并指定应用的根组件。 默认情况下,应用的根组件是 App 组件 (App.razor)。 链接对 AddInteractiveServerRenderMode 的调用,为应用配置交互式服务器端呈现(交互式 SSR):

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

注意

如果应用尚未更新以包含 Antiforgery 中间件,请在调用 UseAuthorization 后添加以下行:

app.UseAntiforgery();

Components 文件夹中为可路由组件创建 Pages 文件夹。 以下示例是 Counter 组件,它基于 Blazor 项目模板中的 Counter 组件。

Components/Pages/Counter.razor

@page "/counter"
@rendermode InteractiveServer

<PageTitle>Counter</PageTitle>

<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++;
    }
}

运行项目并导航到 /counter 中的可路由 Counter 组件。

有关命名空间的详细信息,请参阅组件命名空间部分。

从 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()
{
    return new RazorComponentResult<Welcome>(new { Message = "Hello, world!" });
}

仅返回呈现组件的 HTML 标记。 布局和 HTML 页面标记不会随该组件自动呈现。 若要生成完整的 HTML 页面,应用可维护一个为 <html><head><body> 和其他标记提供 HTML 标记的 Blazor 布局。 对于本部分中的示例,该组件包含在组件定义文件 Welcome.razor 顶部带有 @layoutRazor 指令的布局。 以下示例假定应用具有名为 RazorComponentResultLayout 的布局 (Components/Layout/RazorComponentResultLayout.razor):

@using BlazorSample.Components.Layout
@layout RazorComponentResultLayout

通过将 Layout 文件夹的 @using 语句移动到应用的 _Imports.razor 文件中,可避免将其置于单个组件中。

有关详细信息,请参阅 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 组件

其他资源

预呈现 ASP.NET Core Razor 组件