Modos de renderização Blazor do ASP.NET Core
Este artigo explica o controle da renderização de componentes do Razor em Blazor Web Apps, seja em tempo de compilação ou runtime.
Essas diretrizes não se aplicam a aplicativos autônomos Blazor WebAssembly. Blazor WebAssembly os aplicativos são renderizados apenas no cliente por meio de um tempo de execução baseado em WebAssembly do lado do cliente e não têm conceito de modo de renderização. Se um modo de renderização for aplicado a um componente em um aplicativo Blazor WebAssembly, a designação do modo de renderização não terá influência na renderização do componente.
Modos de renderização
Cada componente em um Blazor Web App adota um modo de renderização para determinar o modelo de hospedagem que utiliza, onde é renderizado e se é ou não interativo.
A tabela a seguir mostra os modos de renderização disponíveis para a renderização de componentes do Razor em um Blazor Web App. Para aplicar um modo de renderização a um componente, utilize a diretiva @rendermode
na instância do componente ou na definição do componente. Mais adiante neste artigo, são mostrados exemplos para cada cenário de modo de renderização.
Nome | Descrição | Local de renderização | Interativo |
---|---|---|---|
Servidor estático | Renderização do lado do servidor estática (SSR estática) | Servidor | Não |
Servidor interativo | Renderização interativa no lado do servidor (SSR interativo) usando Blazor Server. | Servidor | Sim |
WebAssembly interativo | Renderização do lado do cliente (CSR) usando Blazor WebAssembly†. | Cliente | Sim |
Auto interativo | SSR interativa usando Blazor Server inicialmente e, em seguida, CSR em visitas subsequentes depois que o pacote Blazor é baixado. | Servidor, depois o cliente | Sim |
†A renderização do lado do cliente (CSR) é considerada interativa. A "renderização do lado do cliente interativa" e a "CSR interativa" não são usadas pelo setor ou na documentação Blazor.
A pré-renderização estão habilitada por padrão para componentes interativos. As diretrizes para controlar a pré-renderização são fornecidas mais adiante neste artigo. Para ver a terminologia geral do setor sobre conceitos de renderização de cliente e servidor, confira Conceitos básicos do Blazor do ASP.NET Core.
Os exemplos a seguir demonstram a configuração do modo de renderização do componente com alguns recursos básicos do componente Razor.
Para testar os comportamentos do modo de renderização localmente, você pode colocar os seguintes componentes em um aplicativo criado a partir do modelo de projeto do Blazor Web App. Quando criar o aplicativo, selecione as opções dos menus suspensos (Visual Studio) ou aplique as opções da CLI (CLI do .NET ) para habilitar a interatividade do lado do servidor e do lado do cliente. Para obter diretrizes sobre como criar um Blazor Web App, consulte Ferramentas do ASP.NET Core Blazor.
Habilitar o suporte a modos de renderização interativos
Um Blazor Web App deve ser configurado para dar suporte a modos de renderização interativos. As seguintes extensões são aplicadas automaticamente aos aplicativos criados a partir do modelo de projeto do Blazor Web App durante a criação do aplicativo. Os componentes individuais ainda são obrigados a declarar seu modo de renderização de acordo com a seção Modos de Renderização depois que os pontos de extremidade e serviços do componente forem configurados no arquivo Program
do aplicativo.
Os serviços para componentes Razor são adicionados chamando AddRazorComponents.
Extensões do construtor de componentes:
- AddInteractiveServerComponents adiciona serviços para dar suporte à renderização de componentes do Servidor Interativo.
- AddInteractiveWebAssemblyComponents adiciona serviços para dar suporte à renderização de componentes do WebAssembly Interativo.
MapRazorComponents descobre os componentes disponíveis e especifica o componente raiz do aplicativo (o primeiro componente carregado), que por padrão é o componente App
(App.razor
).
Extensões do construtor de convenções de ponto de extremidade:
- AddInteractiveServerRenderMode configura a renderização interativa do lado do servidor (SSR interativa) para o aplicativo.
- AddInteractiveWebAssemblyRenderMode configura o modo de renderização interativa WebAssembly para o aplicativo.
Observação
Para obter orientação sobre a colocação da API nos exemplos a seguir, inspecione o arquivo Program
de um aplicativo gerado a partir do modelo de projeto do Blazor Web App. Para obter diretrizes sobre como criar um Blazor Web App, consulte Ferramentas do ASP.NET Core Blazor.
Exemplo 1: o arquivo da API Program
a seguir adiciona serviços e configuração para habilitar a SSR interativa:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
Exemplo 2: a API do arquivo Program
a seguir adiciona serviços e configuração para habilitar o modo de renderização do WebAssembly Interativo:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
.AddInteractiveWebAssemblyRenderMode();
Exemplo 3: a seguinte API do arquivo Program
adiciona serviços e configurações para habilitar os modos de renderização Auto Interativo, do WebAssembly Interativo e do Servidor Interativo:
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents()
.AddInteractiveWebAssemblyComponents();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode()
.AddInteractiveWebAssemblyRenderMode();
Blazor usa o modelo de hospedagem Blazor WebAssembly para fazer download e executar componentes que utilizam o modo de renderização WebAssembly Interativo. É obrigatório um projeto cliente separado para configurar a hospedagem Blazor WebAssembly para esses componentes. O projeto cliente contém o código de inicialização do host Blazor WebAssembly e configura o runtime do .NET para execução em um navegador. O modelo do Blazor Web App adiciona esse projeto cliente quando você seleciona a opção de habilitar a interatividade do WebAssembly. Todos os componentes que utilizam o modo de renderização do WebAssembly Interativo devem ser criados a partir do projeto cliente, para que sejam incluídos no lote de aplicativos baixado.
Aplicar um modo de renderização a uma instância de componente
Para aplicar um modo de renderização a uma instância de componente, use o atributo @rendermode
Razor da diretiva em que o componente é utilizado.
No exemplo a seguir, a renderização interativa do lado do servidor (SSR interativa) é aplicada à instância do componente Dialog
:
<Dialog @rendermode="InteractiveServer" />
Observação
Os modelos do Blazor incluem uma diretiva estática using
para RenderMode no arquivo _Imports
do aplicativo (Components/_Imports.razor
) para sintaxe mais curta @rendermode
:
@using static Microsoft.AspNetCore.Components.Web.RenderMode
Sem a diretiva anterior, os componentes devem especificar a classe estática RenderMode na sintaxe @rendermode
:
<Dialog @rendermode="RenderMode.InteractiveServer" />
Você também pode referenciar instâncias do modo de renderização personalizada instanciadas diretamente com a configuração personalizada. Para obter mais informações, confira a seção Modos de renderização de abreviação personalizados mais adiante neste artigo.
Aplicar um modo de renderização a uma definição de componente
Para especificar o modo de renderização de um componente como parte da sua definição, utilize a diretiva @rendermode
Razor e o atributo de modo de renderização correspondente.
@page "..."
@rendermode InteractiveServer
A aplicação de um modo de renderização a uma definição de componente é comumente utilizada quando se aplica um modo de renderização a uma página específica. As páginas roteáveis utilizam o mesmo modo de renderização que o componente Router que renderizou a página.
Tecnicamente, @rendermode
é uma Razordiretiva e um Razoratributo de diretiva. A semântica é semelhante, mas existem diferenças. A diretiva @rendermode
está na definição do componente, de modo que a instância do modo de renderização referenciada deve ser estática. O atributo de diretiva @rendermode
pode receber qualquer instância de modo de renderização.
Observação
Os autores de componentes devem evitar acoplar a implementação de um componente a um modo de renderização específico. Em vez disso, os autores de componentes normalmente devem projetar componentes para dar suporte a qualquer modo de renderização ou modelo de hospedagem. A implementação de um componente deve evitar suposições sobre o local em que ele está sendo executado (servidor ou cliente) e deve se degradar suavemente quando renderizado estaticamente. A especificação do modo de renderização na definição do componente pode ser necessária se o componente não for diretamente instanciado (como no caso de um componente de página roteável) ou para especificar um modo de renderização para todas as instâncias do componente.
Aplicar um modo de renderização a todo o aplicativo
Para definir o modo de renderização de todo o aplicativo, indique o modo de renderização no componente interativo de nível mais alto na hierarquia de componentes do aplicativo que não é um componente raiz.
Observação
Não há suporte para tornar um componente raiz interativo, como o componente App
. Portanto, o modo de renderização de todo o aplicativo não pode ser definido diretamente pelo componente App
.
Para aplicativos com base no modelo de projeto do Blazor Web App, um modo de renderização atribuído a todo o aplicativo normalmente é especificado, em que o componente Routes
é usado no componente App
(Components/App.razor
):
<Routes @rendermode="InteractiveServer" />
O componente Router propaga seu modo de renderização para as páginas que roteia.
Normalmente, você também deve definir o mesmo modo de renderização interativo no componente HeadOutlet
, que também é encontrado no componente App
de um Blazor Web App gerado a partir do modelo do projeto:
<HeadOutlet @rendermode="InteractiveServer" />
Para aplicativos que adotam um modo de renderização interativa do lado do cliente (WebAssembly ou renderização Automática) e habilitam o modo de renderização para todo o aplicativo por meio do componente Routes
:
- Coloque ou mova os arquivos de layout e navegação da pasta
Components/Layout
do aplicativo de servidor para a pastaLayout
do projeto.Client
. Crie uma pastaLayout
no projeto.Client
se ela não existir. - Coloque ou mova os componentes da pasta do aplicativo de servidor
Components/Pages
para a pastaPages
do projeto.Client
. Crie uma pastaPages
no projeto.Client
se ela não existir. - Coloque ou mova o componente
Routes
da pastaComponents
do aplicativo de servidor para a pasta raiz do projeto.Client
.
Para habilitar a interatividade global ao criar um Blazor Web App:
- Visual Studio: defina a lista suspensa Local de interatividade como Global.
- CLI do .NET: use a opção
-ai|--all-interactive
.
Para obter mais informações, confira Ferramentas para ASP.NET Core Blazor.
Aplicar um modo de renderização programaticamente
Propriedades e campos podem atribuir um modo de renderização.
A segunda abordagem descrita nesta seção, definir o modo de renderização por instância do componente, é especialmente útil quando a especificação do aplicativo exige que um ou mais componentes adotem a SSR estática em um aplicativo globalmente interativo. Esse cenário é abordado na seção Páginas de SSR estática em um aplicativo globalmente interativo mais adiante neste artigo.
Definir o modo de renderização pela definição do componente
Uma definição de componente pode definir um modo de renderização por meio de um campo privado:
@rendermode pageRenderMode
...
@code {
private static IComponentRenderMode pageRenderMode = InteractiveServer;
}
Definir o modo de renderização pela instância do componente
O exemplo a seguir aplica a renderização interativa do lado do servidor (SSR interativa) a qualquer solicitação.
<Routes @rendermode="PageRenderMode" />
...
@code {
private IComponentRenderMode? PageRenderMode => InteractiveServer;
}
Informações adicionais sobre a propagação do modo de renderização são fornecidas na seção Propagação do modo de renderização mais adiante neste artigo. A seção Páginas de SSR estática em um aplicativo globalmente interativo mostra como usar a abordagem anterior para adotar a SSR estática em um aplicativo globalmente interativo.
Detectar o local de renderização, a interatividade e o modo de renderização atribuído no runtime
As propriedades ComponentBase.RendererInfo
e ComponentBase.AssignedRenderMode
permitem que o aplicativo detecte detalhes sobre o local, a interatividade e o modo de renderização atribuído de um componente:
RendererInfo.Name
retorna o local em que o componente está sendo executado:Static
: no servidor (SSR) e incapaz de interatividade.Server
: no servidor (SSR) e capaz de interatividade após a pré-geração.WebAssembly
: no cliente (CSR) e capaz de interatividade após a pré-geração.WebView
: no dispositivo nativo e capaz de interatividade após a pré-geração.
RendererInfo.IsInteractive
indica se o componente dá suporte à interatividade no momento da renderização. O valor étrue
ao renderizar interativamente oufalse
ao pré-gerar ou para SSR estático (Platform.Name
deStatic
).ComponentBase.AssignedRenderMode
expõe o modo de renderização atribuído do componente:InteractiveServer
para Servidor interativo.InteractiveAuto
Auto interativo.InteractiveWebAssembly
para WebAssembly interativo.
Os componentes usam essas propriedades para renderizar o conteúdo, dependendo de sua localização ou status de interatividade. Por exemplo, um formulário pode ser desabilitado durante a pré-geração e habilitado quando o componente se torna interativo:
<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;
}
}
}
O exemplo a seguir mostra como renderizar a marcação para dar suporte à execução de uma ação HTML regular se o componente for renderizado estaticamente:
@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>
}
No exemplo anterior:
- Quando o valor de
AssignedRenderMode
énull
, o componente adota SSR estático. O tratamento de eventos Blazor não está funcional em um navegador com SSR estático, portanto, o componente envia um formulário (solicitação GET) com uma cadeia de caracteres de consultatitleFilter
definida como o valor<input>
do usuário. O componenteMovie
(/movie
) pode ler a cadeia de caracteres de consulta e processar o valor detitleFilter
para renderizar o componente com os resultados filtrados. - Caso contrário, o modo de renderização é qualquer um dos
InteractiveServer
,InteractiveWebAssembly
ouInteractiveAuto
. O componente é capaz de usar um delegado do manipulador de eventos (FilterMovies
) e o valor associado ao elemento<input>
(titleFilter
) para filtrar filmes interativamente na conexão da tela de fundo SignalR.
Exemplos de documentação do Blazor para Blazor Web Apps
Ao usar um Blazor Web App, a maioria dos componentes de exemplo de documentação do Blazor requerem interatividade para funcionar e demonstrar os conceitos abordados pelos artigos. Ao testar um componente de exemplo fornecido por um artigo, certifique-se de que o aplicativo adote interatividade global ou de que o componente adote um modo de renderização interativo.
Pré-renderização
A pré-renderização é o processo de renderizar inicialmente o conteúdo da página no servidor sem habilitar manipuladores de eventos para controles renderizados. O servidor gera a interface do usuário HTML da página o mais rápido possível em resposta à solicitação inicial, o que dá a sensação de que o aplicativo é mais responsivo aos usuários. A pré-renderização também pode melhorar a SEO (Otimização do Mecanismo de Pesquisa) ao renderizar conteúdos de resposta ao HTTP inicial no quais os mecanismos de pesquisa usam para calcular a classificação da página.
A pré-renderização estão habilitada por padrão para componentes interativos.
A navegação interna para roteamento interativo não envolve a solicitação de novo conteúdo de página do servidor. Portanto, a pré-renderização não ocorre para solicitações de página internas, inclusive para a navegação aprimorada. Para obter mais informações, consulte Roteamento estático versus interativo, Roteamento interativo e pré-renderização e Navegação avançada e tratamento de formulários.
A desabilitação da pré-renderização usando as técnicas a seguir só entra em vigor para modos de renderização de nível superior. Se um componente pai especificar um modo de renderização, as configurações de pré-renderização dos respectivos filhos serão ignoradas. Esse comportamento está sendo investigado por possíveis alterações com o lançamento do .NET 10 em novembro de 2025.
Para desabilitar a pré-geração de uma instância de componente, passe o sinalizador prerender
com um valor para o modo de renderização false
:
<... @rendermode="new InteractiveServerRenderMode(prerender: false)" />
<... @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)" />
<... @rendermode="new InteractiveAutoRenderMode(prerender: false)" />
Para desabilitar a pré-renderização em uma definição de componente:
@rendermode @(new InteractiveServerRenderMode(prerender: false))
@rendermode @(new InteractiveWebAssemblyRenderMode(prerender: false))
@rendermode @(new InteractiveAutoRenderMode(prerender: false))
Para desabilitar a pré-renderização de todo o aplicativo, indique o modo de renderização no componente interativo de nível mais alto na hierarquia de componentes do aplicativo que não é um componente raiz.
Para aplicativos com base no modelo de projeto do Blazor Web App, um modo de renderização atribuído a todo o aplicativo é especificado, em que o componente Routes
é usado no componente App
(Components/App.razor
). O exemplo a seguir define o modo de renderização do aplicativo como Servidor Interativo com a pré-renderização desabilitada:
<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Além disso, desabilite a pré-renderização para o componente HeadOutlet
no componente App
:
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Não há suporte para tornar um componente raiz, como o componente App
, interativo com a diretiva @rendermode
na parte superior do arquivo de definição do componente raiz (.razor
). Portanto, a pré-renderização não pode ser desabilitada diretamente pelo componente App
.
Renderização do lado do servidor estática (SSR estática)
Os componentes usam SSR estática (renderização estática no lado do servidor). O componente é renderizado para o streaming de resposta e a interatividade não é habilitada.
No exemplo a seguir, não há designação para o modo de renderização do componente, portanto o componente herda o modo de renderização de seu pai. Como nenhum componente ancestral especifica um modo de renderização, o componente a seguir é renderizado estaticamente no servidor. O botão não é interativo e não chama o método UpdateMessage
quando selecionado. O valor de message
não é alterado, e o componente não é renderizado novamente em resposta aos eventos da interface do usuário.
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!";
}
}
Se estiver usando o componente anterior localmente em um Blazor Web App, coloque o componente na pasta Components/Pages
do projeto do servidor. O projeto do servidor é o projeto da solução com um nome que não termina em .Client
. Quando o aplicativo estiver em execução, navegue até /render-mode-1
na barra de endereços do navegador.
Durante o SSR estático, Razor as solicitações de páginas de componentes são processadas pelo processamento de solicitações de pipeline de middleware ASP.NET Core do lado do servidor para roteamento e autorização. Recursos Blazor dedicados para roteamento e autorização não estão operacionais porque Razor os componentes não são renderizados durante o processamento de solicitação no lado do servidor. Blazor Os recursos do roteador no componente Routes
que não estão disponíveis durante o SSR estático incluem a exibição:
Conteúdo não autorizado (
<NotAuthorized>...</NotAuthorized>
) (NotAuthorized): Blazor Web Apps normalmente processam solicitações não autorizadas no servidor personalizando o comportamento do Middleware de Autorização.Conteúdo não encontrado (
<NotFound>...</NotFound>
) (NotFound): os Blazor Web Apps normalmente processam solicitações de URL incorretas no servidor exibindo a UI 404 integrada do navegador ou retornando uma página 404 personalizada (ou outra resposta) por meio do middleware do ASP.NET Core (por exemplo,UseStatusCodePagesWithRedirects
/ documentação da API).
Se o aplicativo exibir interatividade no nível raiz, o processamento de solicitação do ASP.NET Core no lado do servidor não será envolvido após o SSR estático inicial, o que significa que os recursos Blazor anteriores funcionam conforme o esperado.
A navegação aprimorada com SSR estático requer atenção especial ao carregar o JavaScript. Para obter mais informações, confira JavaScript do ASP.NET Core Blazor com renderização estática do lado do servidor (SSR estática).
Renderização do lado do servidor interativa (SSR interativa)
A renderização interativa do lado do servidor (SSR interativa) renderiza o componente interativamente do servidor usando Blazor Server. As interações do usuário são tratadas por meio de uma conexão em tempo real com o navegador. A conexão de circuito é estabelecida quando o componente Servidor é renderizado.
No exemplo a seguir, o modo de renderização é definido como SSR interativa adicionando @rendermode InteractiveServer
à definição do componente. O botão chama o método UpdateMessage
quando selecionado. O valor de message
é alterado, e o componente é renderizado novamente para atualizar a mensagem na interface do usuário.
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!";
}
}
Se estiver usando o componente anterior em um Blazor Web App, coloque o componente na pasta Components/Pages
do projeto do servidor†. O projeto do servidor é o projeto da solução com um nome que não termina em .Client
. Quando o aplicativo estiver em execução, navegue até /render-mode-2
na barra de endereços do navegador.
Importante
†Se o aplicativo adotar o WebAssembly global ou a renderização automática global por meio do componente Routes
, componentes individuais que especificam um SSR interativo (@rendermode InteractiveServer
) no seu arquivo de definição de componente (.razor
) serão colocados na pasta Pages
do projeto .Client
.
Colocar componentes SSR interativos no projeto .Client
é contraintuitivo porque esses componentes são renderizados apenas no servidor.
Se você colocar um componente SSR interativo na pasta Components/Pages
de um aplicativo global WebAssembly ou automático do projeto do servidor, o componente será pré-renderizado normalmente e exibido brevemente no navegador do usuário. No entanto, o roteador do lado do cliente não consegue localizar o componente, o que acaba resultando em uma mensagem 404 – Não Encontrado no navegador.
Portanto, coloque os componentes SSR interativos na pasta Pages
do projeto .Client
se o aplicativo adotar o WebAssembly global ou a renderização automática global por meio do componente Routes
.
Renderização do lado do cliente (CSR)
A renderização do lado do cliente (CSR) renderiza o componente interativamente no cliente usando Blazor WebAssembly. O runtime do .NET e o lote de aplicativos são baixados e armazenados em cache quando o componente do WebAssembly é renderizado inicialmente. Os componentes que utilizam CSR devem ser criados em um projeto cliente separado que configure o host Blazor WebAssembly.
No exemplo a seguir, o modo de renderização esta definido como CSR com @rendermode InteractiveWebAssembly
. O botão chama o método UpdateMessage
quando selecionado. O valor de message
é alterado, e o componente é renderizado novamente para atualizar a mensagem na interface do usuário.
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!";
}
}
Se estiver usando o componente anterior localmente em um Blazor Web App, coloque o componente na pasta Pages
do projeto do cliente. O projeto do cliente é o projeto da solução com um nome que termina em .Client
. Quando o aplicativo estiver em execução, navegue até /render-mode-3
na barra de endereços do navegador.
Renderização automática (Auto)
A Renderização Automática (Auto) determina como renderizar o componente em runtime. O componente é inicialmente renderizado do lado do servidor com interatividade utilizando o modelo de hospedagem Blazor Server. O runtime do .NET e o lote de aplicativos são baixados para o cliente em segundo plano e armazenados em cache para que possam ser utilizados em visitas futuras.
O Modo de renderização automática nunca altera dinamicamente o modo de renderização de um componente já presente na página. O modo de renderização automática toma uma decisão inicial sobre qual tipo de interatividade usar para um componente, depois o componente mantém esse tipo de interatividade enquanto está na página. Um fator nessa decisão inicial é considerar se já existem componentes na página com interatividade entre WebAssembly/Servidor. O modo automático prefere selecionar um modo de renderização que corresponda ao modo de renderização dos componentes interativos existentes. A razão pela qual o modo Automático prefere usar um modo de interatividade existente é evitar a introdução de um novo tempo de execução interativo que não compartilhe o estado com o runtime existente.
Os componentes que utilizam o modo de renderização automática devem ser criados a partir de um projeto cliente separado que configure o host Blazor WebAssembly.
No exemplo a seguir, o componente é interativo durante todo o processo. O botão chama o método UpdateMessage
quando selecionado. O valor de message
é alterado, e o componente é renderizado novamente para atualizar a mensagem na interface do usuário. Inicialmente, o componente é renderizado interativamente a partir do servidor, mas nas visitas subsequentes ele é renderizado a partir do cliente depois que o runtime do .NET e o lote de aplicativos são baixados e armazenados em cache.
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!";
}
}
Se estiver usando o componente anterior localmente em um Blazor Web App, coloque o componente na pasta Pages
do projeto do cliente. O projeto do cliente é o projeto da solução com um nome que termina em .Client
. Quando o aplicativo estiver em execução, navegue até /render-mode-4
na barra de endereços do navegador.
Propagação do modo de renderização
Os modos de renderização se propagam pela hierarquia de componentes.
Regras para aplicação dose modos de renderização:
- O modo de renderização padrão é Estático.
- Os modos de renderização Servidor Interativo (InteractiveServer), WebAssembly Interativo (InteractiveWebAssembly) e Auto Interativo (InteractiveAuto) podem ser usados com um componente, inclusive usando diferentes modos de renderização para componentes irmãos.
- Não é possível alternar para um modo de renderização interativo diferente em um componente filho. Por exemplo, um componente Servidor não pode ser filho de um componente WebAssembly.
- Os parâmetros passados para um componente filho interativo a partir de um pai estático devem ser JSON serializáveis. Isso significa que você não pode passar fragmentos de renderização ou conteúdo filho de um componente pai Estático para um componente filho Interativo.
Os exemplos a seguir usam um componente SharedMessage
que não é roteável, nem uma página. O componente SharedMessage
agnóstico ao modo de renderização não aplica um modo de renderização com uma diretiva @attribute
. Se estiver testando esses cenários com um Blazor Web App, coloque o componente a seguir na pasta Components
do aplicativo.
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!";
}
}
Herança do modo de renderização
Se o componente SharedMessage
for colocado em um componente pai renderizado estaticamente, o componente SharedMessage
também será renderizado estaticamente e não será interativo. O botão não chama UpdateMessage
e a mensagem não é atualizada.
RenderMode5.razor
:
@page "/render-mode-5"
<SharedMessage />
Se o componente SharedMessage
for colocado em um componente que define o modo de renderização, ele herdará o modo de renderização aplicado.
No exemplo a seguir, o componente SharedMessage
é interativo em uma conexão SignalR com o cliente. O botão chama UpdateMessage
e a mensagem é atualizada.
RenderMode6.razor
:
@page "/render-mode-6"
@rendermode InteractiveServer
<SharedMessage />
Componentes filhos com diferentes modos de renderização
No exemplo a seguir, ambos os componentes SharedMessage
são pré-renderizados e aparecem quando a página é exibida no navegador.
- O primeiro componente
SharedMessage
com renderização interativa do lado do servidor (SSR interativa) é interativo depois que o circuito SignalR é estabelecido. - O segundo componente
SharedMessage
com renderização do lado do cliente é interativo após o download do lote de aplicativos Blazor e o runtime do .NET estar ativo no cliente.
RenderMode7.razor
:
@page "/render-mode-7"
<SharedMessage @rendermode="InteractiveServer" />
<SharedMessage @rendermode="InteractiveWebAssembly" />
Componente filho com um parâmetro serializável
O exemplo a seguir demonstra um componente filho interativo que recebe um parâmetro. Os parâmetros devem ser serializáveis.
RenderMode8.razor
:
@page "/render-mode-8"
<SharedMessage @rendermode="InteractiveServer" Greeting="Welcome!" />
Parâmetros de componentes não serializáveis, como o conteúdo filho ou fragmento de renderização, não são aceitos. No exemplo a seguir, passar o conteúdo filho para o componente SharedMessage
resulta em um erro de runtime.
RenderMode9.razor
:
@page "/render-mode-9"
<SharedMessage @rendermode="InteractiveServer">
Child content
</SharedMessage>
Erro:
System.InvalidOperationException: não é possível passar o parâmetro 'ChildContent' para o componente 'SharedMessage' com o modo de renderização 'InteractiveServerRenderMode'. Isso ocorre porque o parâmetro é do tipo delegado 'Microsoft.AspNetCore.Components.RenderFragment', que é um código arbitrário e não pode ser serializado.
Para contornar a limitação anterior, encapsule o componente filho em outro componente que não tenha o parâmetro. Essa é a abordagem adotada no modelo de projeto do Blazor Web App com o componente Routes
(Components/Routes.razor
) para encapsular o componente Router.
WrapperComponent.razor
:
<SharedMessage>
Child content
</SharedMessage>
RenderMode10.razor
:
@page "/render-mode-10"
<WrapperComponent @rendermode="InteractiveServer" />
No exemplo anterior:
- O conteúdo filho é passado para o componente
SharedMessage
sem gerar um erro de runtime. - O componente
SharedMessage
é renderizado interativamente no servidor.
Componente filho com um modo de renderização diferente do pai
Não tente aplicar a um componente filho um modo de renderização interativo diferente do modo de renderização de seu pai.
O seguinte componente resulta em um erro de runtime quando o componente é renderizado:
RenderMode11.razor
:
@page "/render-mode-11"
@rendermode InteractiveServer
<SharedMessage @rendermode="InteractiveWebAssembly" />
Erro:
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.
Páginas de SSR estática em um aplicativo globalmente interativo
Existem casos em que as especificações do aplicativo requerem que os componentes adotem a SSR estática (renderização estática do lado do servidor) e sejam executados apenas no servidor, enquanto o rest do aplicativo utiliza um modo de renderização interativo.
Essa abordagem só é útil quando o aplicativo tem páginas específicas que não podem funcionar com a renderização interativa do Servidor ou do WebAssembly. Por exemplo, adote essa abordagem para páginas que dependem da leitura/gravação de cookies HTTP e só podem funcionar em um ciclo de solicitação/resposta em vez de renderização interativa. Para as páginas que funcionam com renderização interativa, você não deve forçá-las a usar a renderização SSR estática, pois ela é menos eficiente e menos dinâmica para o usuário final.
Marque qualquer página do componente Razor com o atributo [ExcludeFromInteractiveRouting]
atribuído com a diretiva @attribute
Razor:
@attribute [ExcludeFromInteractiveRouting]
A aplicação do atributo faz com que a navegação na página saia do roteamento interativo. A navegação de entrada é forçada a executar um recarregamento de página inteira, resolvendo a página por meio de roteamento interativo. O recarregamento de página inteira força o componente raiz de nível superior, normalmente o componente App
(App.razor
), a gerar novamente do servidor, permitindo que o aplicativo mude para um modo de renderização de nível superior diferente.
O método de extensão HttpContext.AcceptsInteractiveRouting
permite que o componente detecte se [ExcludeFromInteractiveRouting]
é aplicado à página atual.
No componente App
, use o padrão no exemplo a seguir:
- Páginas que não são anotadas com
[ExcludeFromInteractiveRouting]
padrão para o modo de renderizaçãoInteractiveServer
com interatividade global. Você pode substituirInteractiveServer
porInteractiveWebAssembly
ouInteractiveAuto
para especificar um modo de renderização global padrão diferente. - Páginas anotadas com
[ExcludeFromInteractiveRouting]
adotar SSR estático (PageRenderMode
é atribuídonull
).
<!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;
}
Uma alternativa ao uso do método de extensão HttpContext.AcceptsInteractiveRouting
é ler metadados de ponto de extremidade manualmente usando HttpContext.GetEndpoint()?.Metadata
.
Existem dois métodos que podem ser adotadas para o controle detalhado dos modos de renderização, cada uma descrita nas subseções a seguir:
Área (pasta) de componentes de SSR estática: você possui uma área (pasta) no aplicativo com componentes que devem adotar a SSR estática e compartilhar o mesmo prefixo de caminho de rota. O aplicativo gerencia o modo de renderização de forma global, ajustando o modo de renderização no componente
Routes
dentro do componenteApp
, baseando-se no caminho para a pasta.Componentes de SSR estática espalhados pelo aplicativo: você tem componentes espalhados pelo aplicativo em vários locais que precisam adotar a SSR estática e serem executados apenas no servidor. Os componentes exclusivos para SSR estática não estão em uma única pasta e não compartilham um prefixo de caminho de rota comum. O aplicativo gerencia o modo de renderização individualmente para cada componente, configurando o modo de renderização com a diretiva
@rendermode
nas instâncias dos componentes. A reflexão é utilizada no componenteApp
para estabelecer o modo de renderização no componenteRoutes
.
Em ambos os casos, o componente que precisa adotar a SSR estática também deve forçar um recarregamento completo da página.
Os exemplos a seguir utilizam o parâmetro em cascata HttpContext para determinar se a página está sendo renderizada estaticamente. Um null
HttpContext indica que o componente está sendo renderizado de maneira interativa, o que é útil como um sinal no código do aplicativo para disparar um recarregamento completo da página.
Área (pasta) de componentes de SSR estática
O método descrito nesta subseção é empregada pelo modelo de projeto do Blazor Web App com autenticação individual e interatividade em escala global.
Uma área (pasta) do aplicativo abriga os componentes que precisam adotar a renderização estática do lado do servidor (SSR estática) e serem executados exclusivamente no servidor. Os componentes dessa pasta compartilham o mesmo prefixo de caminho de rota. Por exemplo, os componentes IdentityRazor do modelo de projeto do Blazor Web App estão localizados na pasta Components/Account/Pages
e compartilham o prefixo de caminho raiz /Account
.
Essa pasta também inclui um arquivo _Imports.razor
, que impõe um layout de conta personalizado aos componentes ali presentes:
@using BlazorSample.Components.Account.Shared
@layout AccountLayout
A pasta Shared
preserva o componente de layout AccountLayout
. O componente usa HttpContext para determinar se o componente adotou a SSR estática. Os componentes Identity precisam ser renderizados no servidor com SSR estática porque configuram cookies Identity. Se o valor de HttpContext for null
, o componente será renderizado interativamente, e um recarregamento completo da página será realizado ao chamar NavigationManager.Refresh com forceLoad
definido como true
. Isso força a página a fazer uma nova renderização completa usando a SSR estática.
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);
}
}
}
Observação
No modelo de projeto do Blazor Web App, há um segundo arquivo de layout (ManageLayout.razor
na Components/Account/Shared
pasta) para componentes Identity na pasta Components/Account/Pages/Manage
. A pasta Manage
tem seu próprio arquivo _Imports.razor
para ser aplicado ao ManageLayout
dos componentes na pasta. Em seus próprios aplicativos, o uso de arquivos _Imports.razor
aninhados é um método útil para aplicar layouts personalizados a grupos de páginas.
No componente App
, qualquer pedido de um componente na pasta Account
resulta na aplicação de um modo de renderização null
, que impõe a SSR estática. Solicitações de outros componentes recebem o aplicativo global do modo de renderização SSR interativa (InteractiveServer
).
Importante
Aplicar um modo de renderização null
não garante sempre uma SSR estática. Isso só ocorre dessa forma usando o método apresentado nesta seção.
Um modo de renderização null
é, na prática, equivalente a não especificar um modo de renderização, o que faz com que o componente herde o modo de renderização do seu elemento pai. Nesse caso, o componente App
é renderizado com SSR estática, então um modo de renderização null
faz com que o componente Routes
herde a SSR estática do componente App
. Se um modo de renderização nulo for especificado para um componente filho em que o elemento pai utiliza um modo de renderização interativo, o filho herda esse mesmo modo interativo.
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};
}
No código apresentado anteriormente, substitua o espaço reservado {INTERACTIVE RENDER MODE}
pelo valor apropriado, dependendo se o rest do aplicativo deve adotar a renderização global InteractiveServer, InteractiveWebAssembly ou InteractiveAuto.
Os componentes que devem adotar a SSR estática na pasta Account
não são necessários para definir o layout, que é aplicado por meio do arquivo _Imports.razor
. Os componentes não definem um modo de renderização porque devem renderizar com SSR estática. Não precisa fazer mais nada para que os componentes na pasta Account
implementem a SSR estática.
Componentes de SSR estática espalhados pelo aplicativo
Como mencionado na subseção anterior, o aplicativo gerencia o modo de renderização dos componentes configurando-o de forma global no componente App
. Como alternativa, o componente App
também pode adotar modos de renderização específicos para cada componente, permitindo que componentes distribuídos pelo aplicativo adotem a SSR estática. Essa subseção descreve o método.
O aplicativo possui um layout personalizado que pode ser aplicado a componentes em diferentes partes do aplicativo. Geralmente, coloca-se um componente compartilhado pelo aplicativo na pasta Components/Layout
. O componente usa HttpContext para determinar se o componente adotou a SSR estática. Se o valor de HttpContext for null
, o componente será renderizado interativamente, e um recarregamento completo da página será realizado ao chamar NavigationManager.Refresh com forceLoad
definido como true
. Isso dispara uma solicitação ao servidor para o componente.
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);
}
}
}
No componente App
, a reflexão é usada para definir o modo de renderização. Qualquer modo de renderização atribuído ao arquivo de definição de cada componente é aplicado ao componente Routes
.
Components/App.razor
:
<Routes @rendermode="RenderModeForPage" />
...
@code {
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
private IComponentRenderMode? RenderModeForPage =>
HttpContext.GetEndpoint()?.Metadata.GetMetadata<RenderModeAttribute>()?
.Mode;
}
Cada componente que precisa adotar a SSR estática define o layout personalizado e não especifica um modo de renderização. Não especificar um modo de renderização resulta em um valor null
de RenderModeAttribute.Modeno componente App
, o que resulta em nenhum modo de renderização atribuído à instância do componente Routes
e à implementação da SSR estática.
Importante
Aplicar um modo de renderização null
não garante sempre uma SSR estática. Isso só ocorre dessa forma usando o método apresentado nesta seção.
Um modo de renderização null
é, na prática, equivalente a não especificar um modo de renderização, o que faz com que o componente herde o modo de renderização do seu elemento pai. Nesse caso, o componente App
é renderizado com SSR estática, então um modo de renderização null
faz com que o componente Routes
herde a SSR estática do componente App
. Se um modo de renderização nulo for especificado para um componente filho em que o elemento pai utiliza um modo de renderização interativo, o filho herda esse mesmo modo interativo.
Nada mais deve ser feito para que os componentes imponham o SSR estático do que aplicar o layout personalizado sem definir um modo de renderização interativo:
@layout BlazorSample.Components.Layout.StaticSsrLayout
Os componentes interativos em torno do aplicativo evitam a aplicação do layout SSR estático personalizado e definem apenas um modo de renderização interativo apropriado, que após reflexão no App
componente é aplicado ao Routes
componente:
@rendermode {INTERACTIVE RENDER MODE}
No código apresentado anteriormente, substitua o espaço reservado {INTERACTIVE RENDER MODE}
pelo valor correspondente, dependendo se o componente deve adotar a renderização InteractiveServer, InteractiveWebAssembly ou InteractiveAuto.
Os serviços do lado do cliente falham em ser resolvidos durante a pré-renderização
Supondo que a pré-renderização não esteja desabilitada para um componente ou para o aplicativo, um componente no projeto .Client
é pré-renderizado no servidor. Como o servidor não tem acesso a serviços do Blazor registrados do lado do cliente, não é possível injetar esses serviços em um componente sem receber um erro de que o serviço não pode ser encontrado durante a pré-renderização.
Por exemplo, considere o seguinte componente Home
no projeto .Client
em um Blazor Web App com WebAssembly interativo global ou renderização automática interativa. O componente tenta injetar IWebAssemblyHostEnvironment para obter o nome do ambiente.
@page "/"
@inject IWebAssemblyHostEnvironment Environment
<PageTitle>Home</PageTitle>
<h1>Home</h1>
<p>
Environment: @Environment.Environment
</p>
Nenhum erro de tempo de compilação ocorre, mas ocorre um erro de runtime durante a pré-renderização:
Não é possível fornecer um valor para a propriedade "Environment" no tipo "BlazorSample.Client.Pages.Home". Não há nenhum serviço registrado do tipo "Microsoft.AspNetCore.Components.WebAssembly.Hosting.IWebAssemblyHostEnvironment".
Esse erro ocorre porque o componente deve ser compilado e executado no servidor durante a pré-renderização, mas IWebAssemblyHostEnvironment não é um serviço registrado no servidor.
Se o aplicativo não exigir o valor durante a pré-renderização, esse problema poderá ser resolvido injetando IServiceProvider para obter o serviço em vez do próprio tipo de serviço:
@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;
}
}
}
No entanto, a abordagem anterior não será útil se a sua lógica exigir um valor durante a pré-renderização.
Você também pode evitar o problema se desabilitar a pré-renderização do componente, mas essa é uma medida extrema e em muitos casos pode não atender às especificações do componente.
Há três abordagens que você pode adotar para resolver esse cenário. As seguintes são listadas da mais recomendada para a menos recomendada:
Recomendado para serviços de estrutura compartilhada: Para serviços de estrutura compartilhada que simplesmente não estão registrados no lado do servidor no projeto principal, registre os serviços no projeto principal, o que os torna disponíveis durante a pré-renderização. Para obter um exemplo desse cenário, consulte as diretrizes para serviços HttpClient em Chamar uma API Web de um aplicativo Blazor ASP.NET Core.
Recomendado para serviços fora da estrutura compartilhada: criar uma implementação de serviço personalizada para o serviço no servidor. Use o serviço normalmente em componentes interativos do projeto
.Client
. Para obter uma demonstração dessa abordagem, confira Ambientes do Blazor do AsP.NET Core.Crie uma abstração de serviço e crie implementações para o serviço nos projetos do
.Client
e do servidor. Registre os serviços em cada projeto. Insira o serviço personalizado no componente.Talvez você possa adicionar uma referência de pacote de projeto
.Client
a um pacote do lado do servidor e fazer fallback ao usar a API do lado do servidor durante a pré-renderização no servidor.
Descobrir componentes de assemblies adicionais
Assemblies adicionais devem ser divulgados à estrutura Blazor para descobrir componentes roteáveis Razor em projetos referenciados. Para obter mais informações, confira Roteamento e navegação do Blazor no ASP.NET Core.
Fechamento de circuitos quando não existem componentes do Servidor Interativo restantes
Os componentes do Servidor Interativo lidam com eventos da interface do usuário da Web utilizando uma conexão em tempo real com o navegador conhecida como circuito. Um circuito e seu estado associado são criados quando um componente do Servidor Interativo raiz é renderizado. O circuito é fechado quando não existem componentes do Servidor Interativo restantes na página, o que libera recursos do servidor.
Modos de renderização abreviados personalizados
A diretiva @rendermode
recebe um único parâmetro que é uma instância estática do tipo IComponentRenderMode. O atributo de diretiva @rendermode
pode receber qualquer instância do modo de renderização, estático ou não. A estrutura Blazor fornece a classe estática RenderMode com alguns modos de renderização predefinidos por conveniência, mas você pode criar o seu próprio.
Normalmente, um componente usa a seguinte diretiva @rendermode
para desabilitar a pré-renderização:
@rendermode @(new InteractiveServerRenderMode(prerender: false))
No entanto, considere o exemplo a seguir, que cria um modo de renderização de do lado do servidor interativo com abreviação sem pré-renderizar por meio do arquivo _Imports
do aplicativo (Components/_Imports.razor
):
public static IComponentRenderMode InteractiveServerWithoutPrerendering { get; } =
new InteractiveServerRenderMode(prerender: false);
Use o modo de renderização abreviada em componentes em toda a pasta Components
:
@rendermode InteractiveServerWithoutPrerendering
Como alternativa, uma única instância de componente pode definir um modo de renderização personalizado por meio de um campo privado:
@rendermode interactiveServerWithoutPrerendering
...
@code {
private static IComponentRenderMode interactiveServerWithoutPrerendering =
new InteractiveServerRenderMode(prerender: false);
}
No momento, a abordagem do modo de renderização abreviado provavelmente só será útil para reduzir o detalhamento da especificação do sinalizador prerender
. A abordagem abreviada poderá ser mais útil no futuro se outros sinalizadores estiverem disponíveis para renderização interativa e se você quiser criar modos de renderização abreviados com diferentes combinações de sinalizadores.
Injeção de serviço por meio de um arquivo de importação de nível superior (_Imports.razor
)
Esta seção só se aplica a Blazor Web Apps.
Um arquivo de importação de nível superior na pasta Components
(Components/_Imports.razor
) injeta suas referências em todos os componentes na hierarquia de pastas, que inclui o componente App
(App.razor
). O componente App
é sempre renderizado estaticamente, mesmo se a pré-renderização de um componente de página está desabilitada. Portanto, injetar serviços por meio do arquivo de importações de nível superior resulta na resolução de duas instâncias do serviço em componentes de página.
Para resolver esse cenário, injete o serviço em um novo arquivo de importações colocado na pasta Pages
(Components/Pages/_Imports.razor
). A partir desse local, o serviço só é resolvido uma vez nos componentes da página.
Recursos adicionais
- Compactação WebSocket
- ASP.NET Core Blazor JavaScript com renderização estática do lado do servidor (SSR estática)
- Valores/parâmetros em cascata e limites o modo de renderização: consulte também a seção Parâmetros em cascata no nível raiz anteriormente no artigo.
- Bibliotecas de classes principais ASP.NET Razor (RCLs) com renderização estática do lado do servidor (SSR estático)
- ASP.NET Core Blazor JavaScript com renderização estática do lado do servidor (SSR estática)
- Valores/parâmetros em cascata e limites o modo de renderização: consulte também a seção Parâmetros em cascata no nível raiz anteriormente no artigo.
- Bibliotecas de classes principais ASP.NET Razor (RCLs) com renderização estática do lado do servidor (SSR estático)