режимы отрисовки ASP.NET Core Blazor
Примечание.
Это не последняя версия этой статьи. В текущем выпуске см . версию .NET 9 этой статьи.
Внимание
Эта информация относится к предварительному выпуску продукта, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
В текущем выпуске см . версию .NET 9 этой статьи.
В этой статье объясняется управление отрисовкой компонентов во Blazor Web Appвремя компиляции Razor или во время выполнения.
Это руководство не относится к автономным Blazor WebAssembly приложениям. Blazor WebAssemblyприложения отображаются только на клиенте с помощью клиентской среды выполнения WebAssembly и не имеют концепции режима отрисовки. Если режим отрисовки применяется к компоненту в Blazor WebAssembly приложении, назначение режима отрисовки не влияет на отрисовку компонента.
Режимы отрисовки
Каждый компонент в режиме Blazor Web App отрисовки принимает режим отрисовки, чтобы определить модель размещения, которая используется, где она отрисовывается, и независимо от того, является ли она интерактивной.
В следующей таблице показаны доступные режимы отрисовки компонентов отрисовки Razor в .Blazor Web App Чтобы применить режим отрисовки к компоненту, используйте @rendermode
директиву для экземпляра компонента или определения компонента. Далее в этой статье показаны примеры для каждого сценария режима отрисовки.
Имя | Описание | Расположение отрисовки | Интерактивный |
---|---|---|---|
Статический сервер | Статическое отрисовка на стороне сервера (статический SSR) | Сервер | Нет |
Интерактивный сервер | Интерактивная отрисовка на стороне сервера (интерактивная среда SSR) с помощью Blazor Server. | Сервер | Да |
Интерактивный webAssembly | Отрисовка на стороне клиента (CSR) с помощью Blazor WebAssembly†. | Клиент | Да |
Интерактивное авто | Интерактивная служба SSR, используемая Blazor Server изначально, а затем CSR при последующих посещениях после Blazor скачивания пакета. | Сервер, а затем клиент | Да |
†Клиентская отрисовка (CSR) считается интерактивной. "Интерактивная отрисовка на стороне клиента" и "интерактивная CSR" не используются в отрасли или в Blazor документации.
Предварительная подготовка включена по умолчанию для интерактивных компонентов. Инструкции по управлению предварительной подготовкой приведены далее в этой статье. Общие отраслевые терминологии в концепциях отрисовки клиентов и серверов см. в ASP.NET основных Blazor принципах.
В следующих примерах демонстрируется настройка режима отрисовки компонента с помощью нескольких основных Razor компонентов.
Чтобы протестировать поведение режима отрисовки локально, можно разместить следующие компоненты в приложении, созданном Blazor Web App на основе шаблона проекта. При создании приложения выберите параметры в раскрывающихся меню (Visual Studio) или примените параметры ИНТЕРФЕЙСА командной строки (.NET CLI), чтобы включить взаимодействие на стороне сервера и на стороне клиента. Инструкции по созданию Blazor Web Appприложения см. в разделе "Инструменты для ASP.NET Core Blazor".
Включение поддержки интерактивных режимов отрисовки
Необходимо Blazor Web App настроить для поддержки интерактивных режимов отрисовки. Следующие расширения автоматически применяются к приложениям, созданным из Blazor Web App шаблона проекта во время создания приложения. Отдельные компоненты по-прежнему необходимы для объявления режима отрисовки в разделе режимов отрисовки после настройки служб компонентов и конечных точек в файле приложения Program
.
Службы для Razor компонентов добавляются путем вызова AddRazorComponents.
Расширения построителя компонентов:
- AddInteractiveServerComponents добавляет службы для поддержки отрисовки компонентов интерактивного сервера.
- AddInteractiveWebAssemblyComponents добавляет службы для поддержки отрисовки компонентов Interactive WebAssembly.
MapRazorComponents обнаруживает доступные компоненты и задает корневой компонент для приложения (первый загруженный компонент), который по умолчанию является компонентом App
(App.razor
).
Расширения построителя соглашений конечной точки:
- AddInteractiveServerRenderMode настраивает интерактивную отрисовку на стороне сервера (интерактивная служба SSR) для приложения.
- AddInteractiveWebAssemblyRenderMode настраивает режим отрисовки интерактивного веб-сайта для приложения.
Примечание.
Для ориентации на размещение API в следующих примерах проверьте Program
файл приложения, созданного на основе Blazor Web App шаблона проекта. Инструкции по созданию Blazor Web Appприложения см. в разделе "Инструменты для ASP.NET Core Blazor".
Пример 1. Следующий Program
API файлов добавляет службы и конфигурацию для включения интерактивного SSR:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
Пример 2. Следующий Program
API файлов добавляет службы и конфигурацию для включения режима интерактивной отрисовки WebAssembly:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode();
Пример 3. Следующий Program
API файлов добавляет службы и конфигурацию для включения режима интерактивного сервера, интерактивного веб-сайта и интерактивного автоматического отрисовки:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode();
BlazorBlazor WebAssembly использует модель размещения для скачивания и выполнения компонентов, использующих режим интерактивной отрисовки WebAssembly. Для настройки Blazor WebAssembly размещения этих компонентов требуется отдельный клиентский проект. Клиентский проект содержит код запуска узла Blazor WebAssembly и настраивает среду выполнения .NET для запуска в браузере. Шаблон Blazor Web App добавляет этот клиентский проект для вас при выборе параметра для включения интерактивности WebAssembly. Все компоненты, использующие режим интерактивной отрисовки WebAssembly, должны быть созданы из клиентского проекта, поэтому они включаются в скачанный пакет приложений.
Применение режима отрисовки к экземпляру компонента
Чтобы применить режим отрисовки к экземпляру компонента, используйте @rendermode
Razor атрибут директивы, в котором используется компонент.
В следующем примере к экземпляру Dialog
компонента применяется интерактивная отрисовка на стороне сервера (интерактивная служба SSR):
<Dialog @rendermode="InteractiveServer" />
Примечание.
Blazor шаблоны включают статическую using
директиву для RenderMode файла приложения _Imports
(Components/_Imports.razor
) для более @rendermode
короткого синтаксиса:
@using static Microsoft.AspNetCore.Components.Web.RenderMode
Без предыдущей директивы компоненты должны указывать статический RenderMode класс в @rendermode
синтаксисе:
<Dialog @rendermode="RenderMode.InteractiveServer" />
Можно также ссылаться на экземпляры пользовательского режима отрисовки, созданные непосредственно с пользовательской конфигурацией. Дополнительные сведения см . в разделе "Пользовательские режимы отрисовки " далее в этой статье.
Применение режима отрисовки к определению компонента
Чтобы указать режим отрисовки для компонента в рамках его определения, используйте @rendermode
Razor директиву и соответствующий атрибут режима отрисовки.
@page "..."
@rendermode InteractiveServer
Применение режима отрисовки к определению компонента обычно используется при применении режима отрисовки к определенной странице. Routable pages использует тот же режим отрисовки, что Router и компонент, который отрисовал страницу.
@rendermode
Технически это директива Razorи Razorатрибут директивы. Семантика аналогична, но существуют различия. Директива @rendermode
находится в определении компонента, поэтому экземпляр режима отрисовки, на который ссылается, должен быть статическим. Атрибут директивы может принимать любой @rendermode
экземпляр режима отрисовки.
Примечание.
Авторы компонентов должны избегать связывания реализации компонента с определенным режимом отрисовки. Вместо этого авторы компонентов обычно должны разрабатывать компоненты для поддержки любого режима отрисовки или модели размещения. Реализация компонента должна избежать предположений о том, где она работает (сервер или клиент) и должна ухудшаться корректно при отображении статически. Указание режима отрисовки в определении компонента может потребоваться, если компонент не создается непосредственно (например, с компонентом routable page) или указать режим отрисовки для всех экземпляров компонентов.
Применение режима отрисовки ко всему приложению
Чтобы задать режим отрисовки для всего приложения, укажите режим отрисовки на самом высоком уровне интерактивного компонента в иерархии компонентов приложения, который не является корневым компонентом.
Примечание.
Создание интерактивного корневого компонента, например App
компонента, не поддерживается. Поэтому режим отрисовки для всего приложения не может быть задан непосредственно компонентом App
.
Для приложений на Blazor Web App основе шаблона проекта режим отрисовки, назначенный всему приложению, обычно указывается, где Routes
компонент используется в App
компоненте (Components/App.razor
):
<Routes @rendermode="InteractiveServer" />
Компонент Router распространяет режим отрисовки на страницы, на которые он направляется.
Кроме того, обычно необходимо задать тот же интерактивный режим отрисовки компонентаHeadOutlet
, который также находится в App
компоненте созданного Blazor Web App из шаблона проекта:
<HeadOutlet @rendermode="InteractiveServer" />
Для приложений, которые принимают интерактивный клиентский режим (WebAssembly или auto) отрисовки и включите режим отрисовки Routes
для всего приложения через компонент:
- Поместите или переместите файлы макета и навигации папки приложения
Components/Layout
сервера в папку.Client
проектаLayout
. Создайте папкуLayout
.Client
в проекте, если она не существует. - Поместите или переместите компоненты папки серверного приложения
Components/Pages
в папку.Client
проектаPages
. Создайте папкуPages
.Client
в проекте, если она не существует. - Поместите или переместите
Routes
компонент папки приложенияComponents
сервера в.Client
корневую папку проекта.
Включение глобального Blazor Web Appвзаимодействия при создании:
- Visual Studio: задайте раскрывающийся список расположений интерактивного взаимодействия в глобальном списке.
- .NET CLI: используйте
-ai|--all-interactive
этот параметр.
Дополнительные сведения см. в статье Инструментарий для ASP.NET Core Blazor.
Применение режима отрисовки программно
Свойства и поля могут назначать режим отрисовки.
Второй подход, описанный в этом разделе, настройка режима отрисовки экземпляром компонента особенно полезна, когда спецификация приложения вызывает один или несколько компонентов для внедрения статического SSR в глобально интерактивном приложении. Этот сценарий рассматривается на страницах статического SSR в глобальном интерактивном разделе приложения далее в этой статье.
Настройка режима отрисовки по определению компонента
Определение компонента может определять режим отрисовки через частное поле:
@rendermode pageRenderMode
...
@code {
private static IComponentRenderMode pageRenderMode = InteractiveServer;
}
Настройка режима отрисовки по экземпляру компонента
В следующем примере к любому запросу применяется интерактивная отрисовка на стороне сервера (интерактивная служба SSR).
<Routes @rendermode="PageRenderMode" />
...
@code {
private IComponentRenderMode? PageRenderMode => InteractiveServer;
}
Дополнительные сведения о распространении режима отрисовки приведены в разделе распространения режима отрисовки далее в этой статье. На страницах статического SSR в разделе глобально интерактивного приложения показано, как использовать предыдущий подход для внедрения статического SSR в глобально интерактивном приложении.
Обнаружение расположения отрисовки, интерактивности и назначенного режима отрисовки во время выполнения
ComponentBase.AssignedRenderMode Свойства ComponentBase.RendererInfo позволяют приложению обнаруживать сведения о расположении, интерактивности и назначенном режиме отрисовки компонента:
- RendererInfo.Name возвращает расположение, в котором выполняется компонент:
Static
: на сервере (SSR) и не может взаимодействовать.Server
: на сервере (SSR) и может взаимодействовать после предварительной подготовки.WebAssembly
: на клиенте (CSR) и может взаимодействовать после предварительной подготовки.WebView
: на собственном устройстве и способен взаимодействовать после предварительной подготовки.
- RendererInfo.IsInteractive указывает, поддерживает ли компонент интерактивность во время отрисовки. Значение —
true
при интерактивной отрисовке илиfalse
при предварительной подготовке или для статического SSR (RendererInfo.Name изStatic
). - ComponentBase.AssignedRenderMode предоставляет назначенный компоненту режим отрисовки:
InteractiveServer
для интерактивного сервера.InteractiveAuto
для интерактивного авто.InteractiveWebAssembly
для интерактивного webAssembly.
Компоненты используют эти свойства для отображения содержимого в зависимости от их расположения или состояния интерактивности. В следующих примерах показаны типичные варианты использования.
Отображение содержимого до тех пор, пока компонент не будет интерактивным:
@if (!RendererInfo.IsInteractive)
{
<p>Connecting to the assistant...</p>
}
else
{
...
}
Отключите кнопку, пока компонент не будет интерактивным:
<button @onclick="Send" disabled="@(!RendererInfo.IsInteractive)">
Send
</button>
Отключите форму во время предварительной подготовки и включите форму при интерактивном выполнении компонента:
<EditForm Model="Movie" ...>
<fieldset disabled="@disabled">
...
<button type="submit" >Save</button>
</fieldset>
</EditForm>
@code {
private bool disabled = true;
[SupplyParameterFromForm]
private Movie? Movie { get; set; }
protected override async Task OnInitializedAsync()
{
Movie ??= await ...;
if (RendererInfo.IsInteractive)
{
disabled = false;
}
}
}
Отрисовка разметки для поддержки обычного html-действия, если компонент статически отрисовывается:
@if (AssignedRenderMode is null)
{
// The render mode is Static Server
<form action="/movies">
<input type="text" name="titleFilter" />
<input type="submit" value="Search" />
</form>
}
else
{
// The render mode is Interactive Server, WebAssembly, or Auto
<input @bind="titleFilter" />
<button @onclick="FilterMovies">Search</button>
}
В предыдущем примере:
- Если значение равно
null
, компонент принимает статический AssignedRenderMode SSR. Blazor Обработка событий не работает в браузере со статическим SSR, поэтому компонент отправляет форму (ЗАПРОС GET) со строкой запроса, заданнойtitleFilter
для значения пользователя<input>
. КомпонентMovie
(/movie
) может считывать строку запроса и обрабатывать значениеtitleFilter
для отрисовки компонента с отфильтрованными результатами. - В противном случае режим отрисовки является любым из
InteractiveServer
,InteractiveWebAssembly
илиInteractiveAuto
. Компонент может использовать делегат обработчика событий () и значение, привязанное к<input>
элементу (FilterMovies
titleFilter
) для интерактивного фильтрации фильмов по фоновому SignalR подключению.
Blazor Примеры документации для Blazor Web Apps
При использовании Blazor Web Appбольшинства Blazor компонентов примера документации требуется интерактивность для работы и демонстрации концепций, описанных в статьях. При тестировании примера компонента, предоставленного в статье, убедитесь, что приложение принимает глобальное взаимодействие или компонент принимает интерактивный режим отрисовки.
Предварительная отрисовка
Предварительная отрисовка — это процесс первоначальной отрисовки содержимого страницы на сервере без включения обработчиков событий для отрисованных элементов управления. Сервер выводит HTML-интерфейс страницы как можно скорее в ответ на первоначальный запрос, что делает приложение более адаптивным к пользователям. Предварительная подготовка также может улучшить оптимизацию поисковой системы (SEO), отрисовав содержимое для первоначального HTTP-ответа, используемого поисковыми системами для вычисления ранжирования страниц.
Предварительная подготовка включена по умолчанию для интерактивных компонентов.
Внутренняя навигация для интерактивной маршрутизации не включает запрос нового содержимого страницы с сервера. Таким образом, предварительная подготовка не выполняется для внутренних запросов страниц, в том числе для расширенной навигации. Дополнительные сведения см. в разделе "Статическая и интерактивная маршрутизация", "Интерактивная маршрутизация" и "Предварительная подготовка" и "Улучшенная навигация" и "Обработка форм".
Отключение предварительной подготовки с помощью следующих методов действует только для режимов отрисовки верхнего уровня. Если родительский компонент задает режим отрисовки, параметры предварительной отрисовки дочерних элементов игнорируются. Это поведение находится под следствием возможных изменений с выпуском .NET 10 в ноябре 2025 года.
Чтобы отключить предварительную отрисовку для экземпляра компонента, передайте prerender
флаг со значением false
режима отрисовки:
<... @rendermode="new InteractiveServerRenderMode(prerender: false)" />
<... @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
<... @rendermode="new InteractiveAutoRenderMode(prerender: false)" />
Чтобы отключить предварительную отрисовку в определении компонента, выполните следующие действия.
@rendermode @(new InteractiveServerRenderMode(prerender: false))
@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))
@rendermode @(new InteractiveAutoRenderMode(prerender: false))
Чтобы отключить предварительную отрисовку для всего приложения, укажите режим отрисовки на самом высоком уровне интерактивного компонента в иерархии компонентов приложения, которая не является корневым компонентом.
Для приложений на Blazor Web App основе шаблона проекта режим отрисовки, назначенный всему приложению, указывается, где Routes
компонент используется в App
компоненте (Components/App.razor
). В следующем примере для режима отрисовки приложения устанавливается интерактивный сервер с отключенным предопределенным отображением:
<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Кроме того, отключите предварительную отрисовку компонента HeadOutlet
в компоненте:App
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Создание корневого компонента, например App
компонента, интерактивного с @rendermode
директивой в верхней части файла определения корневого компонента (.razor
) не поддерживается. Поэтому предварительная подготовка не может быть отключена непосредственно компонентом App
.
Статическое отрисовка на стороне сервера (статический SSR)
Компоненты используют статическую отрисовку на стороне сервера (статический SSR). Компонент отрисовывается в поток отклика и интерактивность не включена.
В следующем примере нет обозначения режима отрисовки компонента, поэтому компонент наследует его режим отрисовки от родительского элемента. Так как компонент предка не указывает режим отрисовки, следующий компонент статически отрисовывается на сервере. Кнопка не является интерактивной и не вызывает метод при выборе UpdateMessage
. Значение message
не изменяется, и компонент не переназначется в ответ на события пользовательского интерфейса.
RenderMode1.razor
:
@page "/render-mode-1"
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
При локальном использовании предыдущего компонента Blazor Web Appпоместите компонент в папку проекта Components/Pages
сервера. Серверный проект — это проект решения с именем, который не заканчивается .Client
. При запуске приложения перейдите /render-mode-1
в адресную строку браузера.
Во время статического SSR Razor запросы страниц компонента обрабатываются серверным ASP.NET обработкой запросов конвейера по промежуточного слоя Core для маршрутизации и авторизации. Выделенные Blazor функции маршрутизации и авторизации не работают, так как Razor компоненты не отображаются во время обработки запросов на стороне сервера. Blazor функции маршрутизатора в компоненте Routes
, недоступном во время статического SSR, включают отображение:
Не авторизованное содержимое () () (): Blazor Web Appобычно обрабатывает несанкционированные запросы на сервере, настраивая поведение ПО промежуточного слояNotAuthorized авторизации.
<NotAuthorized>...</NotAuthorized>
Не найдено содержимое () () (): обычно обрабатываются плохие ЗАПРОСы URL-адресов на сервере, отображая встроенный 404 пользовательский интерфейс браузера или возвращая пользовательскую страницу 404 (или другой ответ) с помощью ASP.NET ПО промежуточного слоя Core (например,
UseStatusCodePagesWithRedirects
/ документация по API). Blazor Web AppNotFound<NotFound>...</NotFound>
Если приложение демонстрирует интерактивность корневого уровня, обработка запросов на стороне сервера ASP.NET Core не участвует после первоначального статического SSR, что означает, что предыдущие Blazor функции работают должным образом.
Улучшенная навигация со статическим SSR требует особого внимания при загрузке JavaScript. Дополнительные сведения см. в разделе ASP.NET Core Blazor JavaScript со статическим отображением на стороне сервера (статический SSR).
Интерактивная отрисовка на стороне сервера (интерактивная среда SSR)
Интерактивная отрисовка на стороне сервера (интерактивная служба SSR) отображает компонент интерактивным образом с сервера.Blazor Server Взаимодействие с пользователем обрабатывается через подключение в режиме реального времени с браузером. Подключение к каналу устанавливается при отрисовки компонента сервера.
В следующем примере режим отрисовки устанавливается интерактивный SSR путем добавления @rendermode InteractiveServer
в определение компонента. Кнопка вызывает UpdateMessage
метод при выборе. Значение message
изменений и компонент переназначен для обновления сообщения в пользовательском интерфейсе.
RenderMode2.razor
:
@page "/render-mode-2"
@rendermode InteractiveServer
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
При использовании предыдущего компонента в папке Blazor Web Appпроекта Components/Pages
сервера поместите его в папку. Серверный проект — это проект решения с именем, который не заканчивается .Client
. При запуске приложения перейдите /render-mode-2
в адресную строку браузера.
Отрисовка на стороне клиента (CSR)
Отрисовка на стороне клиента (CSR) обрабатывает компонент интерактивным образом Blazor WebAssemblyна клиенте. Среда выполнения .NET и пакет приложений загружаются и кэшируются при первоначальном отображении компонента WebAssembly. Компоненты, использующие CSR, должны быть созданы из отдельного клиентского Blazor WebAssembly проекта, который настраивает узел.
В следующем примере режим отрисовки имеет значение CSR с @rendermode InteractiveWebAssembly
. Кнопка вызывает UpdateMessage
метод при выборе. Значение message
изменений и компонент переназначен для обновления сообщения в пользовательском интерфейсе.
RenderMode3.razor
:
@page "/render-mode-3"
@rendermode InteractiveWebAssembly
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
При локальном использовании предыдущего компонента поместите компонент Blazor Web Appв папку клиентского проекта Pages
. Клиентский проект — это проект решения с именем, который заканчивается .Client
. При запуске приложения перейдите /render-mode-3
в адресную строку браузера.
Автоматическая отрисовка (авто)
Автоматическая отрисовка (авто) определяет способ отрисовки компонента во время выполнения. Компонент изначально отрисовывается с помощью интерактивной отрисовки на стороне сервера (интерактивная служба SSR) с помощью Blazor Server модели размещения. Среда выполнения .NET и пакет приложений загружаются на клиент в фоновом режиме и кэшируются, чтобы их можно было использовать в будущих визитах.
Режим автоматической отрисовки никогда динамически не изменяет режим отрисовки компонента, уже на странице. Режим автоматической отрисовки принимает первоначальное решение о том, какой тип взаимодействия будет использоваться для компонента, а затем компонент сохраняет этот тип интерактивности до тех пор, пока он находится на странице. Одним из факторов в этом первоначальном решении является рассмотрение того, существуют ли компоненты на странице с интерактивностью WebAssembly/Server. Автоматический режим предпочитает выбрать режим отрисовки, соответствующий режиму отрисовки существующих интерактивных компонентов. Причина, по которой автоматический режим предпочитает использовать существующий режим интерактивного взаимодействия, заключается в том, чтобы избежать внедрения новой интерактивной среды выполнения, которая не предоставляет общий доступ к состоянию существующей среды выполнения.
Компоненты, использующие режим автоматической отрисовки, должны быть созданы из отдельного клиентского Blazor WebAssembly проекта, который настраивает узел.
В следующем примере компонент является интерактивным во время процесса. Кнопка вызывает UpdateMessage
метод при выборе. Значение message
изменений и компонент переназначен для обновления сообщения в пользовательском интерфейсе. Изначально компонент отображается в интерактивном режиме с сервера, но при последующих посещениях он отрисовывается от клиента после скачивания и кэширования пакета приложений .NET.
RenderMode4.razor
:
@page "/render-mode-4"
@rendermode InteractiveAuto
<button @onclick="UpdateMessage">Click me</button> @message
@code {
private string message = "Not updated yet.";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
При локальном использовании предыдущего компонента поместите компонент Blazor Web Appв папку клиентского проекта Pages
. Клиентский проект — это проект решения с именем, который заканчивается .Client
. При запуске приложения перейдите /render-mode-4
в адресную строку браузера.
Распространение режима отрисовки
Режимы отрисовки распространяются вниз иерархии компонентов.
Правила применения режимов отрисовки:
- Режим отрисовки по умолчанию является статическим.
- Интерактивный сервер (InteractiveServer), интерактивный webAssembly (InteractiveWebAssemblyInteractiveAuto) и режимы интерактивного автообрисовки () можно использовать из компонента, включая использование различных режимов отрисовки для компонентов-одноуровневых компонентов.
- Невозможно переключиться на другой интерактивный режим отрисовки в дочернем компоненте. Например, компонент сервера не может быть дочерним компонентом WebAssembly.
- Параметры, передаваемые интерактивному дочернему компоненту из статического родительского элемента, должны быть сериализуемыми в формате JSON. Это означает, что невозможно передать фрагменты отрисовки или дочернее содержимое из статического родительского компонента в интерактивный дочерний компонент.
В следующих примерах используется неизменяемый, нестраничный SharedMessage
компонент. Не зависящий SharedMessage
от режима отрисовки компонент не применяет режим отрисовки с директивой@attribute
. Если вы тестируете эти сценарии с помощью Blazor Web Appследующего компонента, поместите следующий компонент в папку приложения Components
.
SharedMessage.razor
:
<p>@Greeting</p>
<button @onclick="UpdateMessage">Click me</button> @message
<p>@ChildContent</p>
@code {
private string message = "Not updated yet.";
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter]
public string Greeting { get; set; } = "Hello!";
private void UpdateMessage()
{
message = "Somebody updated me!";
}
}
Наследование режима отрисовки
SharedMessage
Если компонент помещается в статически отрисованный родительский компонент, SharedMessage
компонент также отображается статически и не является интерактивным. Кнопка не вызывается UpdateMessage
, и сообщение не обновляется.
RenderMode5.razor
:
@page "/render-mode-5"
<SharedMessage />
SharedMessage
Если компонент помещается в компонент, определяющий режим отрисовки, он наследует примененный режим отрисовки.
В следующем примере SharedMessage
компонент является интерактивным SignalR через подключение к клиенту. Вызовы UpdateMessage
кнопки и обновление сообщения.
RenderMode6.razor
:
@page "/render-mode-6"
@rendermode InteractiveServer
<SharedMessage />
Дочерние компоненты с различными режимами отрисовки
В следующем примере оба SharedMessage
компонента предварительно отображаются и отображаются при отображении страницы в браузере.
- Первый
SharedMessage
компонент с интерактивной отрисовкой на стороне сервера (интерактивный SSR) является интерактивным после SignalR установки канала. - Второй
SharedMessage
компонент с отрисовкой на стороне клиента (CSR) является интерактивным после Blazor скачивания пакета приложений, а среда выполнения .NET активна на клиенте.
RenderMode7.razor
:
@page "/render-mode-7"
<SharedMessage @rendermode="InteractiveServer" />
<SharedMessage @rendermode="InteractiveWebAssembly" />
Дочерний компонент с сериализуемым параметром
В следующем примере показан интерактивный дочерний компонент, который принимает параметр. Параметры должны быть сериализуемыми.
RenderMode8.razor
:
@page "/render-mode-8"
<SharedMessage @rendermode="InteractiveServer" Greeting="Welcome!" />
Несериализируемые параметры компонента, такие как дочернее содержимое или фрагмент отрисовки, не поддерживаются. В следующем примере передача дочернего содержимого SharedMessage
компоненту приводит к ошибке среды выполнения.
RenderMode9.razor
:
@page "/render-mode-9"
<SharedMessage @rendermode="InteractiveServer">
Child content
</SharedMessage>
Ошибка:
System.InvalidOperationException: не удается передать параметр ChildContent компоненту SharedMessage с rendermode "InteractiveServerRenderMode". Это связано с тем, что параметр имеет тип делегата Microsoft.AspNetCore.Components.RenderFragment, который является произвольным кодом и не может быть сериализован.
Чтобы обойти предыдущее ограничение, заключите дочерний компонент в другой компонент, который не имеет параметра. Это подход, принятый в шаблоне Blazor Web App проекта с компонентом Routes
(Components/Routes.razor
) для упаковки Router компонента.
WrapperComponent.razor
:
<SharedMessage>
Child content
</SharedMessage>
RenderMode10.razor
:
@page "/render-mode-10"
<WrapperComponent @rendermode="InteractiveServer" />
В предыдущем примере:
- Дочернее содержимое передается
SharedMessage
компоненту без возникновения ошибки среды выполнения. - Компонент
SharedMessage
отображается в интерактивном режиме на сервере.
Дочерний компонент с другим режимом отрисовки, отличным от родительского
Не пытайтесь применить другой интерактивный режим отрисовки к дочернему компоненту, отличному от режима отрисовки родительского элемента.
Следующий компонент приводит к ошибке среды выполнения при отрисовке компонента:
RenderMode11.razor
:
@page "/render-mode-11"
@rendermode InteractiveServer
<SharedMessage @rendermode="InteractiveWebAssembly" />
Ошибка:
Cannot create a component of type 'BlazorSample.Components.SharedMessage' because its render mode 'Microsoft.AspNetCore.Components.Web.InteractiveWebAssemblyRenderMode' is not supported by Interactive Server rendering.
Статические страницы SSR в глобально интерактивном приложении
Существуют случаи, когда спецификация приложения вызывает компоненты для внедрения статической отрисовки на стороне сервера (статический SSR) и запускается только на сервере, в то время как rest приложение использует интерактивный режим отрисовки.
Этот подход полезен только в том случае, если приложение имеет определенные страницы, которые не могут работать с интерактивным сервером или отрисовкой WebAssembly. Например, используйте этот подход для страниц, которые зависят от чтения и записи файлов cookie HTTP и могут работать только в цикле запроса или ответа вместо интерактивной отрисовки. Для страниц, работающих с интерактивной отрисовкой, их не следует заставлять использовать статическую отрисовку SSR, так как это менее эффективно и менее гибко для конечного пользователя.
Пометьте любую Razor страницу компонента атрибутом, назначенным [ExcludeFromInteractiveRouting]
директивой:@attribute
Razor
@attribute [ExcludeFromInteractiveRouting]
Применение атрибута приводит к переходу на страницу для выхода из интерактивной маршрутизации. Входящий переход принудительно выполняет перезагрузку полностраничной перезагрузки вместо разрешения страницы с помощью интерактивной маршрутизации. Перезагрузка полностраничной перезагрузки заставляет корневой компонент верхнего уровня( как правило App
, компонент (App.razor
) перенаправить с сервера, что позволяет приложению переключиться на другой режим отрисовки верхнего уровня.
Метод RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting расширения позволяет компоненту определить, применяется ли [ExcludeFromInteractiveRouting]
атрибут к текущей странице.
В компоненте App
используйте шаблон в следующем примере:
- Страницы, которые не помечены
[ExcludeFromInteractiveRouting]
атрибутом по умолчанию для режима отрисовки с глобальнойInteractiveServer
интерактивностью. Вы можете заменитьInteractiveServer
InteractiveWebAssembly
InteractiveAuto
или указать другой глобальный режим отрисовки по умолчанию. - Страницы, аннотированные атрибутом, принимают статический
[ExcludeFromInteractiveRouting]
SSR (PageRenderMode
назначается).null
<!DOCTYPE html>
<html>
<head>
...
<HeadOutlet @rendermode="@PageRenderMode" />
</head>
<body>
<Routes @rendermode="@PageRenderMode" />
...
</body>
</html>
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? PageRenderMode
=> HttpContext.AcceptsInteractiveRouting() ? InteractiveServer : null;
}
Альтернативой использованию метода расширения является чтение метаданных конечной RazorComponentsEndpointHttpContextExtensions.AcceptsInteractiveRouting точки вручную.HttpContext.GetEndpoint()?.Metadata
Существует два подхода, которые можно использовать для точного контроля режимов отрисовки, каждый из которых описан в следующих подразделах:
Область (папка) статических компонентов SSR: у вас есть область (папка) приложения с компонентами, которые должны принимать статический SSR и совместно использовать один и тот же префикс пути маршрута. Приложение управляет режимом отрисовки глобально, задав режим отрисовки компонента
Routes
вApp
компоненте на основе пути к папке.Статические компоненты SSR, распределенные по всему приложению: у вас есть компоненты, распределенные по приложению в различных расположениях, которые должны принимать статический SSR и запускаться только на сервере. Статические компоненты SSR не в одной папке и не используют префикс общего пути маршрута. Приложение управляет режимом отрисовки на основе каждого компонента, задав режим отрисовки директивой
@rendermode
в экземплярах компонентов. Отражение используется в компонентеApp
для задания режима отрисовкиRoutes
компонента.
В обоих случаях компонент, который должен принимать статический SSR, также должен принудительно перезагрузить полную страницу.
В следующих примерах HttpContext используется каскадный параметр, чтобы определить, является ли страница статической отрисовки. Указывает null
HttpContext , что компонент отображается в интерактивном режиме, что полезно в качестве сигнала в коде приложения для активации полностраничной перезагрузки.
Область (папка) статических компонентов SSR
Подход, описанный в этом подразделе, используется шаблоном Blazor Web App проекта с индивидуальной проверкой подлинности и глобальной интерактивностью.
Область (папка) приложения содержит компоненты, которые должны принимать статический SSR и запускаться только на сервере. Компоненты в папке используют один и тот же префикс пути маршрута. Например, IdentityRazor компоненты Blazor Web App шаблона проекта находятся в Components/Account/Pages
папке и предоставляют общий доступ к префиксу /Account
корневого пути.
Папка также содержит _Imports.razor
файл, который применяет макет пользовательской учетной записи к компонентам в папке:
@using BlazorSample.Components.Account.Shared
@layout AccountLayout
Папка Shared
поддерживает компонент макета AccountLayout
. Компонент используется HttpContext для определения того, принял ли компонент статический SSR. Identity Компоненты должны отображаться на сервере со статическим SSR, так как они задают Identity файлы cookie. Если значение HttpContext равно null
, компонент отображается в интерактивном режиме, а полностраничная перезагрузка выполняется путем вызова NavigationManager.Refresh с forceLoad
заданным значением true
. Это заставляет полный rerender страницы использовать статический SSR.
Components/Account/Shared/AccountLayout.razor
:
@inherits LayoutComponentBase
@layout BlazorSample.Components.Layout.MainLayout
@inject NavigationManager Navigation
@if (HttpContext is null)
{
<p>Loading...</p>
}
else
{
@Body
}
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnParametersSet()
{
if (HttpContext is null)
{
Navigation.Refresh(forceReload: true);
}
}
}
Примечание.
В шаблоне Blazor Web App проекта есть второй файл макета (ManageLayout.razor
в Components/Account/Shared
папке) для Identity компонентов в папке Components/Account/Pages/Manage
. Папка Manage
имеет собственный _Imports.razor
файл для применения к ManageLayout
компонентам в папке. В собственных приложениях использование вложенных _Imports.razor
файлов — это полезный подход для применения пользовательских макетов к группам страниц.
В компоненте App
любой запрос на компонент в Account
папке применяет режим отрисовки, который применяет статический null
SSR. Другие запросы компонентов получают глобальное приложение интерактивного режима отрисовки SSR (InteractiveServer
).
Внимание
Применение режима отрисовки не всегда применяет статический null
SSR. Это просто происходит, чтобы вести себя таким образом, используя подход, показанный в этом разделе.
null
Режим отрисовки фактически совпадает с указанием режима отрисовки, что приводит к наследоваванию компонента родительского режима отрисовки. В этом случае App
компонент отрисовывается с помощью статического SSR, поэтому null
режим отрисовки App
приводит к Routes
наследованию статического SSR от компонента. Если для дочернего компонента, родительский элемент которого использует режим интерактивной отрисовки, то дочерний элемент наследует тот же интерактивный режим отрисовки.
Components/App.razor
:
<Routes @rendermode="RenderModeForPage" />
...
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.Request.Path.StartsWithSegments("/Account")
? null
: {INTERACTIVE RENDER MODE};
}
В приведенном выше коде измените {INTERACTIVE RENDER MODE}
заполнитель на соответствующее значение в зависимости от того, должен ли rest приложение принять глобальный InteractiveServer, InteractiveWebAssemblyили InteractiveAuto отрисовку.
Компоненты, которые должны принимать статический SSR в папке Account
, не требуются для задания макета, который применяется через _Imports.razor
файл. Компоненты не задают режим отрисовки, так как они должны отображаться со статическим SSR. Для компонентов в папке Account
для принудительного применения статического SSR не требуется ничего дополнительного.
Статические компоненты SSR, распределенные по всему приложению
В предыдущем подразделе приложение управляет режимом отрисовки компонентов, задав режим отрисовки глобально в компонентеApp
. Кроме того, App
компонент также может применять режимы отрисовки для каждого компонента для настройки режима отрисовки, что позволяет компонентам распространяться по приложению для принудительного внедрения статического SSR. В этом подразделе описывается подход.
Приложение имеет пользовательский макет, который можно применить к компонентам вокруг приложения. Обычно общий компонент для приложения помещается в папку Components/Layout
. Компонент используется HttpContext для определения того, принял ли компонент статический SSR. Если значение HttpContext равно null
, компонент отображается в интерактивном режиме, а полностраничная перезагрузка выполняется путем вызова NavigationManager.Refresh с forceLoad
заданным значением true
. Это активирует запрос на сервер для компонента.
Components/Layout/StaticSsrLayout.razor
:
@inherits LayoutComponentBase
@layout MainLayout
@inject NavigationManager Navigation
@if (HttpContext is null)
{
<p>Loading...</p>
}
else
{
@Body
}
@code {
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
protected override void OnParametersSet()
{
if (HttpContext is null)
{
Navigation.Refresh(forceReload: true);
}
}
}
В компоненте App
для задания режима отрисовки используется отражение. Любой режим отрисовки, назначенный файлу определения отдельного компонента, применяется к компоненту Routes
.
Components/App.razor
:
<Routes @rendermode="RenderModeForPage" />
...
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.GetEndpoint()?.Metadata.GetMetadata<RenderModeAttribute>()?
.Mode;
}
Каждый компонент, который должен принимать статический SSR, задает пользовательский макет и не задает режим отрисовки. Не указывая режим отрисовки, он приводит к null
значению RenderModeAttribute.Mode компонента App
, что приводит к тому, что режим отрисовки не назначен Routes
экземпляру компонента и принудительному применению статического SSR.
Внимание
Применение режима отрисовки не всегда применяет статический null
SSR. Это просто происходит, чтобы вести себя таким образом, используя подход, показанный в этом разделе.
null
Режим отрисовки фактически совпадает с указанием режима отрисовки, что приводит к наследоваванию компонента родительского режима отрисовки. В этом случае App
компонент отрисовывается с помощью статического SSR, поэтому null
режим отрисовки App
приводит к Routes
наследованию статического SSR от компонента. Если для дочернего компонента, родительский элемент которого использует режим интерактивной отрисовки, то дочерний элемент наследует тот же интерактивный режим отрисовки.
Для применения статического SSR компоненты не должны выполнять никаких действий, чем применение пользовательского макета без настройки интерактивного режима отрисовки:
@layout BlazorSample.Components.Layout.StaticSsrLayout
Интерактивные компоненты вокруг приложения не применяют пользовательский статический макет SSR и задают только соответствующий интерактивный режим отрисовки, который при отражении в App
компоненте применяется к Routes
компоненту:
@rendermode {INTERACTIVE RENDER MODE}
В приведенном выше коде измените {INTERACTIVE RENDER MODE}
заполнитель на соответствующее значение в зависимости от того, должен ли компонент использовать InteractiveServerили InteractiveWebAssemblyInteractiveAuto отрисовку.
Не удается разрешить клиентские службы во время предварительной подготовки
Если предварительное создание не отключено для компонента или для приложения, компонент в .Client
проекте предварительно отображается на сервере. Так как сервер не имеет доступа к зарегистрированным клиентским Blazor службам, невозможно внедрить эти службы в компонент без получения ошибки, которую служба не может быть найдена во время предварительной отрисовки.
Например, рассмотрим следующий компонент в .Client
проекте в глобальной Blazor Web App интерактивной веб-службе WebAssembly или интерактивной автоматической отрисовке.Home
Компонент пытается внедрить IWebAssemblyHostEnvironment имя среды.
@page "/"
@inject IWebAssemblyHostEnvironment Environment
<PageTitle>Home</PageTitle>
<h1>Home</h1>
<p>
Environment: @Environment.Environment
</p>
Ошибка времени компиляции не возникает, но во время предварительной подготовки возникает ошибка среды выполнения:
Не удается указать значение свойства "Среда" в типе BlazorSample.Client.Pages..Home Зарегистрированная служба типа Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment отсутствует.
Эта ошибка возникает из-за того, что компонент должен компилировать и выполнять на сервере во время предварительной подготовки, но IWebAssemblyHostEnvironment не является зарегистрированной службой на сервере.
Если приложению не требуется значение во время предварительной подготовки, эта проблема может быть решена путем внедрения IServiceProvider для получения службы вместо самого типа службы:
@page "/"
@using Microsoft.AspNetCore.Components.WebAssembly.Hosting
@inject IServiceProvider Services
<PageTitle>Home</PageTitle>
<h1>Home</h1>
<p>
<b>Environment:</b> @environmentName
</p>
@code {
private string? environmentName;
protected override void OnInitialized()
{
if (Services.GetService<IWebAssemblyHostEnvironment>() is { } env)
{
environmentName = env.Environment;
}
}
}
Однако предыдущий подход не полезен, если логика требует значения во время предварительной подготовки.
Вы также можете избежать проблемы, если отключить предварительную отрисовку для компонента, но это крайняя мера, которую необходимо принять во многих случаях, которые могут не соответствовать спецификациям компонента.
Существует три подхода, которые можно предпринять для решения этого сценария. Ниже перечислены наиболее рекомендуемые по крайней мере рекомендуемые значения.
Рекомендуется для служб общей платформы: для служб общей платформы, которые просто не зарегистрированы на стороне сервера в основном проекте, зарегистрируйте службы в основном проекте, что делает их доступными во время предварительной подготовки. Пример этого сценария см. в руководстве по HttpClient службам в вызове веб-API из приложения ASP.NET CoreBlazor.
Рекомендуется использовать службы за пределами общей платформы: создайте пользовательскую реализацию службы для службы на сервере. Обычно используйте службу в интерактивных компонентах
.Client
проекта. Демонстрация этого подхода см. в ASP.NET основных Blazor средах.Создайте абстракцию службы и создайте реализации для службы в
.Client
проектах сервера и серверных проектов. Зарегистрируйте службы в каждом проекте. Внедрение пользовательской службы в компонент.Вы можете добавить
.Client
ссылку на пакет проекта на стороне сервера и вернуться к использованию API на стороне сервера при предварительной подготовке на сервере.
Обнаружение компонентов из дополнительных сборок
Дополнительные сборки должны быть раскрыты в Blazor платформе для обнаружения routable Razor компонентов в ссылочных проектах. Дополнительные сведения см. в статье Маршрутизация ASP.NET Core Blazor и навигация.
Закрытие каналов при отсутствии оставшихся компонентов интерактивного сервера
Компоненты интерактивного сервера обрабатывают события веб-интерфейса с помощью подключения в режиме реального времени к браузеру, называемому каналом. Канал и связанное с ним состояние создаются при отрисовки корневого компонента интерактивного сервера. Канал закрывается, если на странице нет оставшихся компонентов интерактивного сервера, что освобождает ресурсы сервера.
Настраиваемые режимы отрисовки с короткими данными
Директива @rendermode
принимает один параметр, который является статическим экземпляром типа IComponentRenderMode. Атрибут @rendermode
директивы может принимать любой экземпляр режима отрисовки, статический или нет. Платформа Blazor предоставляет статический RenderMode класс с некоторыми предопределенными режимами отрисовки для удобства, но вы можете создать собственные.
Обычно компонент использует следующую @rendermode
директиву для отключения предварительной подготовки:
@rendermode @(new InteractiveServerRenderMode(prerender: false))
Однако рассмотрим следующий пример, который создает короткий интерактивный режим отрисовки на стороне сервера без предварительной подготовки через файл приложения _Imports
(Components/_Imports.razor
):
public static IComponentRenderMode InteractiveServerWithoutPrerendering { get; } =
new InteractiveServerRenderMode(prerender: false);
Используйте сокращенный режим отрисовки в компонентах во всей папке Components
:
@rendermode InteractiveServerWithoutPrerendering
Кроме того, один экземпляр компонента может определить пользовательский режим отрисовки через частное поле:
@rendermode interactiveServerWithoutPrerendering
...
@code {
private static IComponentRenderMode interactiveServerWithoutPrerendering =
new InteractiveServerRenderMode(prerender: false);
}
На данный момент подход к режиму краткого отображения, вероятно, полезен только для уменьшения детализации указания флага prerender
. Короткий подход может оказаться более полезным в будущем, если дополнительные флаги становятся доступными для интерактивной отрисовки, и вы хотите создать режимы отрисовки с различными сочетаниями флагов.
Внедрение службы с помощью файла импорта верхнего уровня (_Imports.razor
)
Этот раздел применяется только к Blazor Web Apps.
Файл импорта верхнего уровня в папку (Components/_Imports.razor
) внедряет ссылки на все компоненты в Components
иерархии папок, включая App
компонент (App.razor
). Компонент App
всегда отображается статически, даже если предварительная отрисовка компонента страницы отключена. Поэтому внедрение служб через файл импорта верхнего уровня приводит к разрешению двух экземпляров службы в компонентах страниц.
Чтобы устранить этот сценарий, введите службу в новый файл импорта, помещенный в папку Pages
(Components/Pages/_Imports.razor
). В этом расположении служба разрешается только один раз в компонентах страниц.
Дополнительные ресурсы
- Сжатие WebSocket
- ASP.NET Core Blazor JavaScript со статическим отображением на стороне сервера (статический SSR)
- Каскадные значения и параметры и границы режима отрисовки: также см . раздел каскадных параметров корневого уровня, приведенный ранее в статье.
- ASP.NET библиотеки классов Core Razor (RCLs) со статическим отображением на стороне сервера (статический SSR)
- ASP.NET Core Blazor JavaScript со статическим отображением на стороне сервера (статический SSR)
- Каскадные значения и параметры и границы режима отрисовки: также см . раздел каскадных параметров корневого уровня, приведенный ранее в статье.
- ASP.NET библиотеки классов Core Razor (RCLs) со статическим отображением на стороне сервера (статический SSR)
ASP.NET Core