Поделиться через


режимы отрисовки 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, должны быть созданы из клиентского проекта, поэтому они включаются в скачанный пакет приложений.

Применение режима отрисовки к экземпляру компонента

Чтобы применить режим отрисовки к экземпляру компонента, используйте @rendermodeRazor атрибут директивы, в котором используется компонент.

В следующем примере к экземпляру 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" />

Можно также ссылаться на экземпляры пользовательского режима отрисовки, созданные непосредственно с пользовательской конфигурацией. Дополнительные сведения см . в разделе "Пользовательские режимы отрисовки " далее в этой статье.

Применение режима отрисовки к определению компонента

Чтобы указать режим отрисовки для компонента в рамках его определения, используйте @rendermodeRazor директиву и соответствующий атрибут режима отрисовки.

@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> элементу (FilterMoviestitleFilter) для интерактивного фильтрации фильмов по фоновому 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, включают отображение:

Если приложение демонстрирует интерактивность корневого уровня, обработка запросов на стороне сервера 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) является интерактивным после BlazorSignalR установки канала.
  • Второй 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] директивой:@attributeRazor

@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, также должен принудительно перезагрузить полную страницу.

В следующих примерах 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). В этом расположении служба разрешается только один раз в компонентах страниц.

Дополнительные ресурсы