Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Примечание.
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.
Предупреждение
Эта версия ASP.NET Core больше не поддерживается. Дополнительные сведения см. в политике поддержки .NET и .NET Core. В текущем выпуске см . версию .NET 9 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .NET 9 этой статьи.
Razor компоненты можно интегрировать в Razor приложения Pages или MVC. Одновременно с отрисовкой страницы или представления можно выполнять предварительную обработку компонентов.
Внимание
Изменения платформы в ASP.NET Core привели к различным наборам инструкций в этой статье. Прежде чем использовать инструкции этой статьи, убедитесь, что селектор версий документов в верхней части этой статьи соответствует версии ASP.NET Core, которую вы планируете использовать для приложения.
Предварительная отрисовка может улучшить оптимизацию для поисковых систем (SEO) за счет визуализации содержимого для первоначального ответа HTTP, который поисковые системы могут использовать для вычисления ранга страницы.
Настроив проект, следуйте рекомендациям в следующих разделах в зависимости от требований проекта:
- Для компонентов, напрямую маршрутизируемых из запросов пользователей. Следуйте этому руководству, когда посетители должны иметь возможность сделать HTTP-запрос в браузере для компонента с директивой
@page
. - Сведения о компонентах, которые не маршрутизируются напрямую из запросов пользователей, см. в разделе Отрисовка компонентов со страницы или представления. Следуйте этому руководству, когда приложение внедряет компоненты в существующие страницы или представления с помощью вспомогательного средства тега компонента.
Настройка
Используйте следующее руководство, чтобы интегрировать Razor компоненты в страницы или представления существующего Razor приложения Pages или MVC.
Добавьте файл импорта в корневой каталог проекта со следующим содержимым. Замените заполнитель
{APP NAMESPACE}
на пространство имен проекта._Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using {APP NAMESPACE}
В файле макета проекта (
Pages/Shared/_Layout.cshtml
в приложениях Razor Pages илиViews/Shared/_Layout.cshtml
в приложениях MVC):Добавьте следующий тег
<base>
и вспомогательную функцию тегов компонента HeadOutlet в элемент<head>
:<base href="~/" /> <component type="typeof(Microsoft.AspNetCore.Components.Web.HeadOutlet)" render-mode="ServerPrerendered" />
Значение
href
(базовый путь к приложению ) в предыдущем примере предполагает, что приложение находится по корневому URL-пути (/
). Если приложение является подпрограммой, см. базовый путь приложения ASP.NET CoreBlazor.Компонент HeadOutlet используется для отрисовки содержимого head (
<head>
) для заголовков страниц (компонент PageTitle) и других элементов head (компонент HeadContent), заданных компонентами Razor. Дополнительные сведения см. в статье Управление содержимым head в приложениях ASP.NET Core Blazor.Добавьте тег
<script>
для скриптаblazor.server.js
непосредственно перед разделом отрисовкиScripts
(@await RenderSectionAsync(...)
):<script src="_framework/blazor.server.js"></script>
Фреймворк добавляет
blazor.server.js
скрипт в приложение. Добавлять файл сценарияblazor.server.js
в приложение вручную не нужно.
Примечание.
Как правило, макет загружается с помощью файла
_ViewStart.cshtml
.Зарегистрируйте службы Blazor Server в том файле
Program.cs
, где регистрируются службы:builder.Services.AddServerSideBlazor();
Добавьте конечную точку концентратора Blazor в конечные точки в файле
Program.cs
, где сопоставляются маршруты. После вызоваMapRazorPages
(для страниц Razor) илиMapControllerRoute
(для MVC) поместите следующую строку:app.MapBlazorHub();
Интегрируйте компоненты в какую-либо страницу или какое-либо представление. Например, добавьте компонент
Counter
в папкуShared
проекта.Pages/Shared/Counter.razor
(Razor Страницы) илиViews/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Страницы:
На странице проекта
Index
в приложении Razor Pages добавьте пространство имен компонента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:
В представлении
Index
приложения MVC добавьте пространство имен компонента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 в приложениях Razor Pages:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
App
в корневой каталог проекта со следующим содержимым.App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(App).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <PageTitle>Not found</PageTitle> <p role="alert">Sorry, there's nothing at this address.</p> </NotFound> </Router>
Добавьте в проект страницу
_Host
со следующим содержимым. Замените заполнитель{APP NAMESPACE}
пространством имен приложения.Pages/_Host.cshtml
:@page @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <component type="typeof(App)" render-mode="ServerPrerendered" />
Примечание.
В предыдущем примере предполагается, что компонент HeadOutlet и скрипт Blazor (
_framework/blazor.server.js
) отрисовываются макетом приложения. Дополнительные сведения см. в разделе Конфигурация.Параметр RenderMode настраивает одно из следующих поведений компонента
App
:- предварительно отрисован на странице.
- компонент отображается как статический HTML на странице или включает необходимые сведения для начальной загрузки приложения Blazor из агента пользователя.
Дополнительные сведения о вспомогательной функции тега компонента, в том числе о передаче параметров и конфигурации RenderMode, см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
В конечных точках
Program.cs
добавьте маршрут с низким приоритетом для страницы_Host
как последнюю конечную точку:app.MapFallbackToPage("/_Host");
Добавьте маршрутизируемые компоненты в проект. Следующий пример представляет собой компонент
RoutableCounter
, основанный на компонентеCounter
в шаблонах проекта Blazor.Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Использование маршрутизируемых компонентов в приложении MVC
Этот раздел описывает добавление компонентов, напрямую маршрутизируемых из запросов пользователей.
Для поддержки маршрутизируемых компонентов Razor в приложениях MVC сделайте следующее:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
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");
Создайте папку
Pages
в приложении MVC и добавьте маршрутизируемые компоненты. Следующий пример представляет собой компонентRoutableCounter
, основанный на компонентеCounter
в шаблонах проекта Blazor.Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Отрисовка компонентов со страницы или представления
Этот раздел касается добавления компонентов на страницы или в представления, которые не могут быть напрямую маршрутизированы из запросов пользователей.
Чтобы отрисовать компонент из страницы или представления, используйте вспомогательную функцию тега компонента.
Отрисовка интерактивных компонентов с отслеживанием состояния
На страницу или в представление Razor можно добавить интерактивные компоненты с отслеживанием состояния.
При отображении страницы или представления:
- компонент предварительно отображается страницей или представлением;
- исходное состояние компонента, используемое для предварительной визуализации, теряется;
- Новое состояние компонента создается при установлении соединения SignalR.
Следующая страница Razor визуализирует компонент Counter
.
<h1>Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
Дополнительные сведения см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Отрисовка неинтерактивных компонентов
На следующей странице Razor компонент Counter
статически подготавливается к просмотру с начальным значением, указанным с помощью формы. Так как этот компонент отображается статически, он не может быть интерактивным:
<h1>Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
Дополнительные сведения см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Пространства имен компонентов
При использовании пользовательской папки для хранения компонентов Razor проекта добавьте пространство имен, представляющее эту папку, либо на страницу/представление, либо в файл _ViewImports.cshtml
. В следующем примере :
- Компоненты хранятся в папке
Components
проекта. - Заполнитель
{APP NAMESPACE}
— это пространство имен проекта.Components
отображает имя папки.
@using {APP NAMESPACE}.Components
Файл _ViewImports.cshtml
находится в папке Pages
приложения Razor Pages или в папке Views
приложения MVC.
Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
Сохранение пререндеренного состояния
Без сохранения предварительно отрисованного состояния все состояния, которые использовались во время предварительной отрисовки, теряются и должны быть созданы заново при полной загрузке приложения. Если какое-либо состояние настроено асинхронно, пользовательский интерфейс может мерцать, так как предварительно отрисованный пользовательский интерфейс заменяется временными заполнителями и затем полностью отрисовывается снова.
Чтобы сохранить состояние для предварительно созданных компонентов, используйте вспомогательный компонент тега состояния сохраняемого компонента (справочный источник). Добавьте тег вспомогательного тега, <persist-component-state />
внутри закрывающего </body>
тега _Host
страницы в приложении, которое предопределено компонентами.
Примечание.
Ссылки в документации на исходный код .NET обычно загружают ветку репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
В Pages/_Host.cshtml
приложениях Blazor , которые находятся ServerPrerendered
в Blazor Server приложении:
<body>
...
<persist-component-state />
</body>
Решите, какое состояние следует сохранить с помощью службы PersistentComponentState. Атрибут, [SupplyParameterFromPersistentComponentState]
применяемый к свойству, регистрирует обратный вызов для сохранения состояния во время предварительной подготовки и загружает его, когда компонент отрисовывается в интерактивном режиме или служба создается.
В следующем примере {TYPE}
заполнитель представляет тип сохраняемых данных (например, WeatherForecast[]
).
@code {
[SupplyParameterFromPersistentComponentState]
public {TYPE} Data { get; set; }
protected override async Task OnInitializedAsync()
{
Data ??= await ...;
}
}
В следующем примере компонент WeatherForecastPreserveState
сохраняет состояние прогноза погоды во время предварительного рендеринга, а затем извлекает это состояние для инициализации компонента.
Вспомогательная функция тега "Сохранение состояния компонента" сохраняет состояние компонента после всех вызовов компонента.
WeatherForecastPreserveState.razor
:
@page "/weather-forecast-preserve-state"
@using BlazorSample.Shared
@inject IWeatherForecastService WeatherForecastService
<PageTitle>Weather Forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (Forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in Forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
[SupplyParameterFromPersistentComponentState]
public WeatherForecast[]? Forecasts { get; set; }
protected override async Task OnInitializedAsync()
{
Forecasts ??= await WeatherForecastService.GetForecastAsync(
DateOnly.FromDateTime(DateTime.Now));
}
}
Решите, какое состояние следует сохранить с помощью службы PersistentComponentState. PersistentComponentState.RegisterOnPersisting регистрирует обратный вызов для сохранения состояния компонента до приостановки приложения. Состояние извлекается при возобновлении работы приложения. Выполните вызов в конце кода инициализации, чтобы избежать потенциального условия гонки во время завершения работы приложения.
В следующем примере :
- Заполнитель
{TYPE}
представляет тип сохраняемых данных (например,WeatherForecast[]
). - Заполнитель
{TOKEN}
— это строка идентификатора состояния (например,fetchdata
).
@implements IDisposable
@inject PersistentComponentState ApplicationState
...
@code {
private {TYPE} data;
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<{TYPE}>(
"{TOKEN}", out var restored))
{
data = await ...;
}
else
{
data = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson("{TOKEN}", data);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
В следующем примере компонент WeatherForecastPreserveState
сохраняет состояние прогноза погоды во время предварительного рендеринга, а затем извлекает это состояние для инициализации компонента.
Вспомогательная функция тега "Сохранение состояния компонента" сохраняет состояние компонента после всех вызовов компонента.
Pages/WeatherForecastPreserveState.razor
:
@page "/weather-forecast-preserve-state"
@using BlazorSample.Shared
@implements IDisposable
@inject IWeatherForecastService WeatherForecastService
@inject PersistentComponentState ApplicationState
<PageTitle>Weather Forecast</PageTitle>
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
private WeatherForecast[] forecasts = Array.Empty<WeatherForecast>();
private PersistingComponentStateSubscription persistingSubscription;
protected override async Task OnInitializedAsync()
{
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
nameof(forecasts), out var restored))
{
forecasts =
await WeatherForecastService.GetForecastAsync(
DateOnly.FromDateTime(DateTime.Now));
}
else
{
forecasts = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
При инициализации компонентов с тем же состоянием, которое использовалось во время предварительной отрисовки, все ресурсоемкие шаги инициализации выполняются только один раз. Отрисованный пользовательский интерфейс также соответствует предварительно отрисованному пользовательскому интерфейсу, поэтому в браузере нет никаких мерцаний.
Сохраняемое предварительно созданное состояние передается клиенту, где оно используется для восстановления состояния компонента. ASP.NET Core Data Protection гарантирует, что данные передаются безопасно в Blazor Server приложениях.
Предопределенный размер состояния и SignalR ограничение размера сообщения
Размер предварительно отрисованного состояния может превышать ограничение на размер сообщения цепи BlazorSignalR, что приводит к следующему:
- Не удается инициализировать SignalR цепь: на клиенте ошибка Circuit host not initialized..
- Пользовательский интерфейс повторного подключения на клиенте отображается при сбое канала. Восстановление невозможно.
Чтобы устранить проблему, используйте любой из следующих подходов:
- Уменьшите объем данных, которые вы помещаете в предварительно созданное состояние.
- SignalR Увеличьте размер сообщения. ПРЕДУПРЕЖДЕНИЕ. Увеличение ограничения может увеличить риск атак типа "отказ в обслуживании" (DoS).
Дополнительные ресурсы Blazor Server
- Управление состоянием: обработка предварительной отрисовки
- Razor Темы, относящиеся к жизненному циклу компонентов и предрендерингу
- Проверка подлинности и авторизация: общие аспекты
- Обработка ошибок: предварительная отрисовка
- Размещение и развертывание серверных приложений ASP.NET Core Blazor
- Устранение угроз: межсайтовые сценарии (XSS)
-
OnNavigateAsync выполняется дважды при предварительной отрисовке: обработка асинхронных событий навигации с помощью
OnNavigateAsync
Предварительная отрисовка может улучшить оптимизацию для поисковых систем (SEO) за счет визуализации содержимого для первоначального ответа HTTP, который поисковые системы могут использовать для вычисления ранга страницы.
Настроив проект, следуйте рекомендациям в следующих разделах в зависимости от требований проекта:
- Маршрутизируемые компоненты: для компонентов, которые напрямую маршрутизируемы из запросов пользователей. Следуйте этому руководству, когда посетители должны иметь возможность сделать HTTP-запрос в браузере для компонента с директивой
@page
. - Рендеринг компонентов из страницы или представления: для компонентов, которые не могут быть напрямую маршрутизированы на основе запросов пользователей. Следуйте этому руководству, когда приложение внедряет компоненты в существующие страницы или представления с помощью вспомогательного средства тега компонента.
Настройка
Используйте следующее руководство, чтобы интегрировать Razor компоненты в страницы или представления существующего Razor приложения Pages или MVC.
Внимание
Использование страницы макета (_Layout.cshtml
) с вспомогательной функцией тега компонента для компонента HeadOutlet является обязательным условием для управления содержимым <head>
, например заголовком страницы (компонент PageTitle), и другими элементами head (компонент HeadContent). Дополнительные сведения см. в статье Управление содержимым head в приложениях ASP.NET Core Blazor.
В файле макета проекта:
Добавьте следующий тег
<base>
и вспомогательную функцию тегов компонента HeadOutlet в элемент<head>
вPages/Shared/_Layout.cshtml
(Razor Pages) илиViews/Shared/_Layout.cshtml
(MVC):<base href="~/" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
Значение
href
(базовый путь к приложению ) в предыдущем примере предполагает, что приложение находится по корневому URL-пути (/
). Если приложение является подпрограммой, см. базовый путь приложения ASP.NET CoreBlazor.Компонент HeadOutlet используется для отрисовки содержимого head (
<head>
) для заголовков страниц (компонент PageTitle) и других элементов head (компонент HeadContent), заданных компонентами Razor. Дополнительные сведения см. в статье Управление содержимым head в приложениях ASP.NET Core Blazor.Добавьте тег
<script>
для скриптаblazor.server.js
непосредственно перед разделом отрисовкиScripts
(@await RenderSectionAsync(...)
) в макете приложения.Pages/Shared/_Layout.cshtml
(Razor Страницы) илиViews/Shared/_Layout.cshtml
(MVC):<script src="_framework/blazor.server.js"></script>
Фреймворк добавляет
blazor.server.js
скрипт в приложение. Добавлять файл сценарияblazor.server.js
в приложение вручную не нужно.
Добавьте файл импорта в корневой каталог проекта со следующим содержимым. Замените заполнитель
{APP NAMESPACE}
на пространство имен проекта._Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.AspNetCore.Components.Web.Virtualization @using Microsoft.JSInterop @using {APP NAMESPACE}
Зарегистрируйте службы Blazor Server в том файле
Program.cs
, где регистрируются службы:builder.Services.AddServerSideBlazor();
Добавьте конечную точку концентратора Blazor в конечные точки в файле
Program.cs
, где сопоставляются маршруты.После вызова
MapRazorPages
(для страниц Razor) илиMapControllerRoute
(для MVC) поместите следующую строку:app.MapBlazorHub();
Интегрируйте компоненты в какую-либо страницу или какое-либо представление. Например, добавьте компонент
Counter
в папкуShared
проекта.Pages/Shared/Counter.razor
(Razor Страницы) илиViews/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Страницы:
На странице проекта
Index
в приложении Razor Pages добавьте пространство имен компонента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:
В представлении
Index
приложения MVC добавьте пространство имен компонента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 в приложениях Razor Pages:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
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), и другими элементами head (компонент HeadContent). Дополнительные сведения см. в статье Управление содержимым head в приложениях ASP.NET Core Blazor.Параметр RenderMode настраивает одно из следующих поведений компонента
App
:- предварительно отрисован на странице.
- компонент отображается как статический HTML на странице или включает необходимые сведения для начальной загрузки приложения Blazor из агента пользователя.
Дополнительные сведения о вспомогательной функции тега компонента, в том числе о передаче параметров и конфигурации RenderMode, см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
В конечных точках
Program.cs
добавьте маршрут с низким приоритетом для страницы_Host
как последнюю конечную точку:app.MapFallbackToPage("/_Host");
Добавьте маршрутизируемые компоненты в проект. Следующий пример представляет собой компонент
RoutableCounter
, основанный на компонентеCounter
в шаблонах проекта Blazor.Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Использование маршрутизируемых компонентов в приложении MVC
Этот раздел описывает добавление компонентов, напрямую маршрутизируемых из запросов пользователей.
Для поддержки маршрутизируемых компонентов Razor в приложениях MVC сделайте следующее:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
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), и другими элементами head (компонент HeadContent). Дополнительные сведения см. в статье Управление содержимым head в приложениях 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");
Создайте папку
Pages
в приложении MVC и добавьте маршрутизируемые компоненты. Следующий пример представляет собой компонентRoutableCounter
, основанный на компонентеCounter
в шаблонах проекта Blazor.Pages/RoutableCounter.razor
:@page "/routable-counter" <PageTitle>Routable Counter</PageTitle> <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Отрисовка компонентов со страницы или представления
Этот раздел касается добавления компонентов на страницы или в представления, которые не могут быть напрямую маршрутизированы из запросов пользователей.
Чтобы отрисовать компонент из страницы или представления, используйте вспомогательную функцию тега компонента.
Отрисовка интерактивных компонентов с отслеживанием состояния
На страницу или в представление Razor можно добавить интерактивные компоненты с отслеживанием состояния.
При отображении страницы или представления:
- компонент предварительно отображается страницей или представлением;
- исходное состояние компонента, используемое для предварительной визуализации, теряется;
- Новое состояние компонента создается при установлении соединения SignalR.
Следующая страница Razor визуализирует компонент Counter
.
<h1>Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
Дополнительные сведения см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Внимание
Использование страницы макета (_Layout.cshtml
) с вспомогательной функцией тега компонента для компонента HeadOutlet является обязательным условием для управления содержимым <head>
, например заголовком страницы (компонент PageTitle), и другими элементами head (компонент HeadContent). Дополнительные сведения см. в статье Управление содержимым head в приложениях 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), и другими элементами head (компонент HeadContent). Дополнительные сведения см. в статье Управление содержимым head в приложениях ASP.NET Core Blazor.
Пространства имен компонентов
При использовании пользовательской папки для хранения компонентов Razor проекта добавьте пространство имен, представляющее эту папку, либо на страницу/представление, либо в файл _ViewImports.cshtml
. В следующем примере :
- Компоненты хранятся в папке
Components
проекта. - Заполнитель
{APP NAMESPACE}
— это пространство имен проекта.Components
отображает имя папки.
@using {APP NAMESPACE}.Components
Файл _ViewImports.cshtml
находится в папке Pages
приложения Razor Pages или в папке Views
приложения MVC.
Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
Сохранение пререндеренного состояния
Без сохранения предварительно отрисованного состояния все состояния, которые использовались во время предварительной отрисовки, теряются и должны быть созданы заново при полной загрузке приложения. Если какое-либо состояние настроено асинхронно, пользовательский интерфейс может мерцать, так как предварительно отрисованный пользовательский интерфейс заменяется временными заполнителями и затем полностью отрисовывается снова.
Для решения этих проблем Blazor поддерживает сохранение состояния на предварительно отрисованной странице с помощью вспомогательного элемента тега "Сохранение состояния компонента". Добавьте тег вспомогательной функции <persist-component-state />
внутрь закрывающего тега </body>
.
Pages/_Layout.cshtml
:
<body>
...
<persist-component-state />
</body>
Решите, какое состояние следует сохранить с помощью службы PersistentComponentState. PersistentComponentState.RegisterOnPersisting регистрирует обратный вызов для сохранения состояния компонента до приостановки приложения. Состояние извлекается при возобновлении работы приложения. Выполните вызов в конце кода инициализации, чтобы избежать потенциального условия гонки во время завершения работы приложения.
В следующем примере компонент 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()
{
if (!ApplicationState.TryTakeFromJson<WeatherForecast[]>(
nameof(forecasts), out var restored))
{
forecasts =
await WeatherForecastService.GetForecastAsync(DateTime.Now);
}
else
{
forecasts = restored!;
}
// Call at the end to avoid a potential race condition at app shutdown
persistingSubscription = ApplicationState.RegisterOnPersisting(PersistData);
}
private Task PersistData()
{
ApplicationState.PersistAsJson(nameof(forecasts), forecasts);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
persistingSubscription.Dispose();
}
}
При инициализации компонентов с тем же состоянием, которое использовалось во время предварительной отрисовки, все ресурсоемкие шаги инициализации выполняются только один раз. Отрисованный пользовательский интерфейс также соответствует предварительно отрисованному пользовательскому интерфейсу, поэтому в браузере нет никаких мерцаний.
Сохраняемое предварительно созданное состояние передается клиенту, где оно используется для восстановления состояния компонента. ASP.NET Core Data Protection гарантирует, что данные передаются безопасно в Blazor Server приложениях.
Предопределенный размер состояния и SignalR ограничение размера сообщения
Размер предварительно отрисованного состояния может превышать ограничение на размер сообщения цепи BlazorSignalR, что приводит к следующему:
- Не удается инициализировать SignalR цепь: на клиенте ошибка Circuit host not initialized..
- Пользовательский интерфейс повторного подключения на клиенте отображается при сбое канала. Восстановление невозможно.
Чтобы устранить проблему, используйте любой из следующих подходов:
- Уменьшите объем данных, которые вы помещаете в предварительно созданное состояние.
- SignalR Увеличьте размер сообщения. ПРЕДУПРЕЖДЕНИЕ. Увеличение ограничения может увеличить риск атак типа "отказ в обслуживании" (DoS).
Дополнительные ресурсы Blazor Server
- Управление состоянием: обработка предварительной отрисовки
- Razor Темы, относящиеся к жизненному циклу компонентов и предрендерингу
- Проверка подлинности и авторизация: общие аспекты
- Обработка ошибок: предварительная отрисовка
- Размещение и развертывание серверных приложений ASP.NET Core Blazor
- Устранение угроз: межсайтовые сценарии (XSS)
Предварительная отрисовка может улучшить оптимизацию для поисковых систем (SEO) за счет визуализации содержимого для первоначального ответа HTTP, который поисковые системы могут использовать для вычисления ранга страницы.
Настроив проект, следуйте рекомендациям в следующих разделах в зависимости от требований проекта:
- Маршрутизируемые компоненты: для компонентов, которые напрямую маршрутизируемы из запросов пользователей. Следуйте этому руководству, когда посетители должны иметь возможность сделать HTTP-запрос в браузере для компонента с директивой
@page
. - Рендеринг компонентов из страницы или представления: для компонентов, которые не могут быть напрямую маршрутизированы на основе запросов пользователей. Следуйте этому руководству, когда приложение внедряет компоненты в существующие страницы или представления с помощью вспомогательного средства тега компонента.
Настройка
Существующее Razor приложение Pages или MVC может интегрировать Razor компоненты в страницы или представления:
В файле макета проекта:
Добавьте следующий тег
<base>
в элемент<head>
вPages/Shared/_Layout.cshtml
(Razor Pages) илиViews/Shared/_Layout.cshtml
(MVC):<base href="~/" />
Значение
href
(базовый путь к приложению ) в предыдущем примере предполагает, что приложение находится по корневому URL-пути (/
). Если приложение является подпрограммой, см. базовый путь приложения ASP.NET CoreBlazor.Добавьте тег
<script>
для скриптаblazor.server.js
непосредственно перед разделом отрисовкиScripts
.Pages/Shared/_Layout.cshtml
(Razor Страницы) илиViews/Shared/_Layout.cshtml
(MVC):... <script src="_framework/blazor.server.js"></script> @await RenderSectionAsync("Scripts", required: false) </body>
Фреймворк добавляет
blazor.server.js
скрипт в приложение. Добавлять файл сценарияblazor.server.js
в приложение вручную не нужно.
Добавьте файл импорта в корневой каталог проекта со следующим содержимым. Замените заполнитель
{APP NAMESPACE}
на пространство имен проекта._Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.JSInterop @using {APP NAMESPACE}
Зарегистрируйте службу Blazor Server в
Startup.ConfigureServices
.В
Startup.cs
:services.AddServerSideBlazor();
Добавьте конечную точку концентратора Blazor в конечные точки (
app.UseEndpoints
)Startup.Configure
.Startup.cs
:endpoints.MapBlazorHub();
Интегрируйте компоненты в какую-либо страницу или какое-либо представление. Например, добавьте компонент
Counter
в папкуShared
проекта.Pages/Shared/Counter.razor
(Razor Страницы) илиViews/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Страницы:
На странице проекта
Index
в приложении Razor Pages добавьте пространство имен компонента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:
В представлении
Index
приложения MVC добавьте пространство имен компонента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 в приложениях Razor Pages:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
App
в корневой каталог проекта со следующим содержимым.App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
Примечание.
В релизе .NET 5.0.1, и для любых дополнительных релизов 5.x, компонент включает набор параметров
Router
, установленный наPreferExactMatches
. Дополнительные сведения см. в разделе "Миграция с ASP.NET Core 3.1 на .NET 5".Добавьте в проект страницу
_Host
со следующим содержимым.Pages/_Host.cshtml
:@page "/blazor" @{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
Для макета компоненты используют общий файл
_Layout.cshtml
.Параметр RenderMode настраивает одно из следующих поведений компонента
App
:- предварительно отрисован на странице.
- компонент отображается как статический HTML на странице или включает необходимые сведения для начальной загрузки приложения Blazor из агента пользователя.
Дополнительные сведения о вспомогательной функции тега компонента, в том числе о передаче параметров и конфигурации RenderMode, см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
В конечных точках
Startup.Configure
Startup.cs
добавьте маршрут с низким приоритетом для страницы_Host
как последнюю конечную точку:endpoints.MapFallbackToPage("/_Host");
В следующем примере показана новая строка в типичной конфигурации конечной точки для приложения:
app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
Добавьте маршрутизируемые компоненты в проект.
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Использование маршрутизируемых компонентов в приложении MVC
Этот раздел описывает добавление компонентов, напрямую маршрутизируемых из запросов пользователей.
Для поддержки маршрутизируемых компонентов Razor в приложениях MVC сделайте следующее:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
App
в корневой каталог проекта со следующим содержимым.App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
Примечание.
В релизе .NET 5.0.1, и для любых дополнительных релизов 5.x, компонент включает набор параметров
Router
, установленный наPreferExactMatches
. Дополнительные сведения см. в разделе "Миграция с ASP.NET Core 3.1 на .NET 5".Добавьте в проект представление
_Host
со следующим содержимым.Views/Home/_Host.cshtml
:@{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
Для макета компоненты используют общий файл
_Layout.cshtml
.Параметр RenderMode настраивает одно из следующих поведений компонента
App
:- предварительно отрисован на странице.
- компонент отображается как статический HTML на странице или включает необходимые сведения для начальной загрузки приложения Blazor из агента пользователя.
Дополнительные сведения о вспомогательной функции тега компонента, в том числе о передаче параметров и конфигурации RenderMode, см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Добавьте действие в контроллер Home.
Controllers/HomeController.cs
:public IActionResult Blazor() { return View("_Host"); }
В конечных точках
Startup.Configure
Startup.cs
добавьте маршрут с низким приоритетом для действия контроллера, которое возвращает представление_Host
:endpoints.MapFallbackToController("Blazor", "Home");
В следующем примере показана новая строка в типичной конфигурации конечной точки для приложения:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapBlazorHub(); endpoints.MapFallbackToController("Blazor", "Home"); });
Добавьте маршрутизируемые компоненты в проект.
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Отрисовка компонентов со страницы или представления
Этот раздел касается добавления компонентов на страницы или в представления, которые не могут быть напрямую маршрутизированы из запросов пользователей.
Чтобы отрисовать компонент из страницы или представления, используйте вспомогательную функцию тега компонента.
Отрисовка интерактивных компонентов с отслеживанием состояния
На страницу или в представление Razor можно добавить интерактивные компоненты с отслеживанием состояния.
При отображении страницы или представления:
- компонент предварительно отображается страницей или представлением;
- исходное состояние компонента, используемое для предварительной визуализации, теряется;
- Новое состояние компонента создается при установлении соединения SignalR.
Следующая страница Razor визуализирует компонент Counter
.
<h1>My Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
Дополнительные сведения см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Отрисовка неинтерактивных компонентов
На следующей странице Razor компонент Counter
статически подготавливается к просмотру с начальным значением, указанным с помощью формы. Так как этот компонент отображается статически, он не может быть интерактивным:
<h1>My Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
Дополнительные сведения см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Пространства имен компонентов
При использовании пользовательской папки для хранения компонентов Razor проекта добавьте пространство имен, представляющее эту папку, либо на страницу/представление, либо в файл _ViewImports.cshtml
. В следующем примере :
- Компоненты хранятся в папке
Components
проекта. - Заполнитель
{APP NAMESPACE}
— это пространство имен проекта.Components
отображает имя папки.
@using {APP NAMESPACE}.Components
Файл _ViewImports.cshtml
находится в папке Pages
приложения Razor Pages или в папке Views
приложения MVC.
Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
Предопределенный размер состояния и SignalR ограничение размера сообщения
Размер предварительно отрисованного состояния может превышать ограничение на размер сообщения цепи BlazorSignalR, что приводит к следующему:
- Не удается инициализировать SignalR цепь: на клиенте ошибка Circuit host not initialized..
- Пользовательский интерфейс повторного подключения на клиенте отображается при сбое канала. Восстановление невозможно.
Чтобы устранить проблему, используйте любой из следующих подходов:
- Уменьшите объем данных, которые вы помещаете в предварительно созданное состояние.
- SignalR Увеличьте размер сообщения. ПРЕДУПРЕЖДЕНИЕ. Увеличение ограничения может увеличить риск атак типа "отказ в обслуживании" (DoS).
Дополнительные ресурсы Blazor Server
- Управление состоянием: обработка предварительной отрисовки
- Razor Темы, относящиеся к жизненному циклу компонентов и предрендерингу
- Проверка подлинности и авторизация: общие аспекты
- Обработка ошибок: предварительная отрисовка
- Размещение и развертывание серверных приложений ASP.NET Core Blazor
- Устранение угроз: межсайтовые сценарии (XSS)
Razor компоненты можно интегрировать в Razor приложения Pages или MVC. Одновременно с отрисовкой страницы или представления можно выполнять предварительную обработку компонентов.
Предварительная отрисовка может улучшить оптимизацию для поисковых систем (SEO) за счет визуализации содержимого для первоначального ответа HTTP, который поисковые системы могут использовать для вычисления ранга страницы.
Настроив проект, следуйте рекомендациям в следующих разделах в зависимости от требований проекта:
- Маршрутизируемые компоненты: для компонентов, которые напрямую маршрутизируемы из запросов пользователей. Следуйте этому руководству, когда посетители должны иметь возможность сделать HTTP-запрос в браузере для компонента с директивой
@page
. - Рендеринг компонентов из страницы или представления: для компонентов, которые не могут быть напрямую маршрутизированы на основе запросов пользователей. Следуйте этому руководству, когда приложение внедряет компоненты в существующие страницы или представления с помощью вспомогательного средства тега компонента.
Настройка
Существующее Razor приложение Pages или MVC может интегрировать Razor компоненты в страницы или представления:
В файле макета проекта:
Добавьте следующий тег
<base>
в элемент<head>
вPages/Shared/_Layout.cshtml
(Razor Pages) илиViews/Shared/_Layout.cshtml
(MVC):+ <base href="~/" />
Значение
href
(базовый путь к приложению ) в предыдущем примере предполагает, что приложение находится по корневому URL-пути (/
). Если приложение является подпрограммой, см. базовый путь приложения ASP.NET CoreBlazor.Добавьте тег
<script>
для скриптаblazor.server.js
непосредственно перед разделом отрисовкиScripts
.Pages/Shared/_Layout.cshtml
(Razor Страницы) илиViews/Shared/_Layout.cshtml
(MVC):... <script src="_framework/blazor.server.js"></script> @await RenderSectionAsync("Scripts", required: false) </body>
Фреймворк добавляет
blazor.server.js
скрипт в приложение. Добавлять файл сценарияblazor.server.js
в приложение вручную не нужно.
Добавьте файл импорта в корневой каталог проекта со следующим содержимым. Замените заполнитель
{APP NAMESPACE}
на пространство имен проекта._Imports.razor
:@using System.Net.Http @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @using Microsoft.AspNetCore.Components.Web @using Microsoft.JSInterop @using {APP NAMESPACE}
Зарегистрируйте службу Blazor Server в
Startup.ConfigureServices
.Startup.cs
:services.AddServerSideBlazor();
Добавьте конечную точку концентратора Blazor в конечные точки (
app.UseEndpoints
)Startup.Configure
.Startup.cs
:endpoints.MapBlazorHub();
Интегрируйте компоненты в какую-либо страницу или какое-либо представление. Например, добавьте компонент
Counter
в папкуShared
проекта.Pages/Shared/Counter.razor
(Razor Страницы) илиViews/Shared/Counter.razor
(MVC):<h1>Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Razor Страницы:
На странице проекта
Index
в приложении Razor Pages добавьте пространство имен компонента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:
В представлении
Index
приложения MVC добавьте пространство имен компонента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 в приложениях Razor Pages:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
App
в корневой каталог проекта со следующим содержимым.App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
Добавьте в проект страницу
_Host
со следующим содержимым.Pages/_Host.cshtml
:@page "/blazor" @{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
Для макета компоненты используют общий файл
_Layout.cshtml
.Параметр RenderMode настраивает одно из следующих поведений компонента
App
:- предварительно отрисован на странице.
- компонент отображается как статический HTML на странице или включает необходимые сведения для начальной загрузки приложения Blazor из агента пользователя.
Дополнительные сведения о вспомогательной функции тега компонента, в том числе о передаче параметров и конфигурации RenderMode, см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
В конечных точках
Startup.Configure
Startup.cs
добавьте маршрут с низким приоритетом для страницы_Host
как последнюю конечную точку:endpoints.MapFallbackToPage("/_Host");
В следующем примере показана новая строка в типичной конфигурации конечной точки для приложения:
app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapBlazorHub(); endpoints.MapFallbackToPage("/_Host"); });
Добавьте маршрутизируемые компоненты в проект.
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Использование маршрутизируемых компонентов в приложении MVC
Этот раздел описывает добавление компонентов, напрямую маршрутизируемых из запросов пользователей.
Для поддержки маршрутизируемых компонентов Razor в приложениях MVC сделайте следующее:
Следуйте указаниям в разделе Конфигурация.
Добавьте компонент
App
в корневой каталог проекта со следующим содержимым.App.razor
:@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound> </Router>
Добавьте в проект представление
_Host
со следующим содержимым.Views/Home/_Host.cshtml
:@{ Layout = "_Layout"; } <app> <component type="typeof(App)" render-mode="ServerPrerendered" /> </app>
Для макета компоненты используют общий файл
_Layout.cshtml
.Параметр RenderMode настраивает одно из следующих поведений компонента
App
:- предварительно отрисован на странице.
- компонент отображается как статический HTML на странице или включает необходимые сведения для начальной загрузки приложения Blazor из агента пользователя.
Дополнительные сведения о вспомогательной функции тега компонента, в том числе о передаче параметров и конфигурации RenderMode, см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Добавьте действие в контроллер Home.
Controllers/HomeController.cs
:public IActionResult Blazor() { return View("_Host"); }
В конечных точках
Startup.Configure
Startup.cs
добавьте маршрут с низким приоритетом для действия контроллера, которое возвращает представление_Host
:endpoints.MapFallbackToController("Blazor", "Home");
В следующем примере показана новая строка в типичной конфигурации конечной точки для приложения:
app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); endpoints.MapBlazorHub(); endpoints.MapFallbackToController("Blazor", "Home"); });
Добавьте маршрутизируемые компоненты в проект.
Pages/RoutableCounter.razor
:@page "/routable-counter" <h1>Routable Counter</h1> <p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { private int currentCount = 0; private void IncrementCount() { currentCount++; } }
Запустите проект и перейдите к маршрутизируемому компоненту
RoutableCounter
по адресу/routable-counter
.
Дополнительные сведения о пространствах имен см. в разделе Пространства имен компонентов.
Отрисовка компонентов со страницы или представления
Этот раздел касается добавления компонентов на страницы или в представления, которые не могут быть напрямую маршрутизированы из запросов пользователей.
Чтобы отрисовать компонент из страницы или представления, используйте вспомогательную функцию тега компонента.
Отрисовка интерактивных компонентов с отслеживанием состояния
На страницу или в представление Razor можно добавить интерактивные компоненты с отслеживанием состояния.
При отображении страницы или представления:
- компонент предварительно отображается страницей или представлением;
- исходное состояние компонента, используемое для предварительной визуализации, теряется;
- Новое состояние компонента создается при установлении соединения SignalR.
Следующая страница Razor визуализирует компонент Counter
.
<h1>My Razor Page</h1>
<component type="typeof(Counter)" render-mode="ServerPrerendered"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
Дополнительные сведения см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Отрисовка неинтерактивных компонентов
На следующей странице Razor компонент Counter
статически подготавливается к просмотру с начальным значением, указанным с помощью формы. Так как этот компонент отображается статически, он не может быть интерактивным:
<h1>My Razor Page</h1>
<form>
<input type="number" asp-for="InitialValue" />
<button type="submit">Set initial value</button>
</form>
<component type="typeof(Counter)" render-mode="Static"
param-InitialValue="InitialValue" />
@functions {
[BindProperty(SupportsGet=true)]
public int InitialValue { get; set; }
}
Дополнительные сведения см. в статье Вспомогательная функция тега компонента в ASP.NET Core.
Пространства имен компонентов
При использовании пользовательской папки для хранения компонентов Razor проекта добавьте пространство имен, представляющее эту папку, либо на страницу/представление, либо в файл _ViewImports.cshtml
. В следующем примере :
- Компоненты хранятся в папке
Components
проекта. - Заполнитель
{APP NAMESPACE}
— это пространство имен проекта.Components
отображает имя папки.
@using {APP NAMESPACE}.Components
Файл _ViewImports.cshtml
находится в папке Pages
приложения Razor Pages или в папке Views
приложения MVC.
Дополнительные сведения см. в статье Компоненты Razor ASP.NET Core.
Предопределенный размер состояния и SignalR ограничение размера сообщения
Размер предварительно отрисованного состояния может превышать ограничение на размер сообщения цепи BlazorSignalR, что приводит к следующему:
- Не удается инициализировать SignalR цепь: на клиенте ошибка Circuit host not initialized..
- Пользовательский интерфейс повторного подключения на клиенте отображается при сбое канала. Восстановление невозможно.
Чтобы устранить проблему, используйте любой из следующих подходов:
- Уменьшите объем данных, которые вы помещаете в предварительно созданное состояние.
- SignalR Увеличьте размер сообщения. ПРЕДУПРЕЖДЕНИЕ. Увеличение ограничения может увеличить риск атак типа "отказ в обслуживании" (DoS).
Дополнительные ресурсы Blazor Server
- Управление состоянием: обработка предварительной отрисовки
- Razor Темы, относящиеся к жизненному циклу компонентов и предрендерингу
- Проверка подлинности и авторизация: общие аспекты
- Обработка ошибок: предварительная отрисовка
- Размещение и развертывание серверных приложений ASP.NET Core Blazor
- Устранение угроз: межсайтовые сценарии (XSS)
ASP.NET Core