Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão do .NET 10 deste artigo.
Aviso
Esta versão do ASP.NET Core não tem mais suporte. Para obter mais informações, consulte a Política de Suporte do .NET e do .NET Core. Para a versão atual, consulte a versão do .NET 10 deste artigo.
Este artigo descreve abordagens comuns para a manutenção dos dados (estado) de um usuário em cenários do lado servidor Blazor.
Manter o estado do usuário
O lado do servidor Blazor é uma estrutura do aplicativo com estado. Na maioria das vezes, o aplicativo mantém uma conexão com o servidor. O estado do usuário é retido na memória do servidor em um circuito.
Os exemplos de estado do usuário retido em um circuito incluem:
- A hierarquia das instâncias de componente e a saída de renderização mais recente na interface do usuário renderizada.
- Os valores de campos e propriedades em instâncias de componentes.
- Os dados retidos nas instâncias de serviço de DI (injeção de dependência) que têm como escopo o circuito.
O estado do usuário também pode ser encontrado em variáveis JavaScript na memória do navegador por meio de chamadas de JavaScript interop.
Se um usuário tiver uma perda temporária de conexão de rede, Blazor tentará reconectar o usuário ao circuito original com o estado original. No entanto, reconectar um usuário ao circuito original na memória do servidor nem sempre é possível:
- O servidor não pode reter um circuito desconectado para sempre. O servidor deve liberar um circuito desconectado após um tempo limite ou quando o servidor estiver sob pressão de memória.
- Em ambientes de implantação com balanceamento de carga de vários servidores, os servidores individuais podem falhar ou ser removidos automaticamente, quando não forem mais necessários para lidar com o volume geral de solicitações. As solicitações de processamento do servidor original para um usuário podem ficar indisponíveis, quando o usuário tenta se reconectar.
- O usuário pode fechar e reabrir o navegador ou recarregar a página, o que remove qualquer estado mantido na memória do navegador. Por exemplo, os valores de variável JavaScript definidos por meio de chamadas de interoperabilidade do JavaScript são perdidos.
Quando um usuário não pode ser reconectado ao circuito original, o usuário recebe um novo circuito com estado inicializado recentemente. Isso é equivalente a fechar e reabrir um aplicativo de desktop.
Quando persistir o estado do usuário
A persistência de estado não é automática. Você deve executar etapas ao desenvolver o aplicativo para implementar a persistência de dados com estado.
Em geral, mantenha o estado entre circuitos em que os usuários estão criando dados ativamente, não simplesmente lendo dados que já existem.
A persistência de dados normalmente só é necessária para o estado de alto valor que os usuários se esforçaram para criar. O estado persistente economiza tempo ou ajuda em atividades comerciais:
- Formulários da Web de várias etapas: demora para um usuário inserir dados novamente em várias etapas concluídas de um formulário da Web de várias etapas, se o estado for perdido. Um usuário perderá o estado nesse cenário, se sair do formulário e retornar mais tarde.
- Carrinhos de compras: qualquer componente comercialmente importante de um aplicativo que representa uma possível receita pode ser mantido. Um usuário que perde seu estado e, portanto, seu carrinho de compras, pode comprar menos produtos ou serviços quando retornar ao site mais tarde.
Um aplicativo só pode persistir o estado do aplicativo. UIs não podem ser persistidas, como instâncias de componentes e suas árvores de renderização. Os componentes e as árvores de renderização geralmente não são serializáveis. Para persistir o estado da interface do usuário, como os nós expandidos de um controle de exibição de árvore, o aplicativo deve usar o código personalizado para modelar o comportamento do estado da interface do usuário como estado serializável do aplicativo.
Persistência do estado do circuito
Durante a renderização do lado do servidor, Blazor Web Apps podem manter o estado de sessão (circuito) de um usuário quando a conexão com o servidor é perdida por um longo período de tempo ou pausada de forma proativa, desde que uma atualização de página inteira não seja iniciada. Isso permite que os usuários retomem a sessão sem perder trabalho não salvo nos seguintes cenários:
- Limitação da guia do navegador
- Usuários de dispositivo móvel trocando de aplicativos
- Interrupções de rede
- Gerenciamento proativo de recursos (pausando circuitos inativos)
- Navegação aprimorada
Os recursos do servidor poderão ser liberados se o estado do circuito puder ser mantido e, em seguida, retomados posteriormente:
- Mesmo se desconectado, um circuito pode continuar a executar o trabalho e consumir CPU, memória e outros recursos. O estado persistente consome apenas uma quantidade fixa de memória que o desenvolvedor controla.
- O estado persistente representa um subconjunto da memória consumida pelo aplicativo, portanto, o servidor não é necessário para acompanhar os componentes do aplicativo e outros objetos do lado do servidor.
O estado é armazenado para dois cenários:
- Estado do componente: estado que os componentes usam para renderização do Servidor Interativo, por exemplo, uma lista de itens recuperados do banco de dados ou um formulário que o usuário está preenchendo.
- Serviços com escopo definido: estado armazenado dentro de um serviço do lado do servidor; por exemplo, o usuário atual.
Condições:
- O recurso só é eficaz para a renderização do Servidor Interativo.
- Se o usuário atualizar a página (aplicativo), o estado persistente será perdido.
- O estado deve ser serializável em JSON. Referências cíclicas ou entidades ORM podem não ser serializadas corretamente.
- Use
@keypara exclusividade ao renderizar componentes em um loop para evitar conflitos de chave. - Mantenha somente o estado necessário. Armazenar dados excessivos pode afetar o desempenho.
- Nenhuma hibernação automática. Você deve aceitar e configurar explicitamente a persistência de estado.
- Nenhuma garantia de recuperação. Se a persistência de estado falhar, o aplicativo retornará à experiência desconectada padrão.
O armazenamento de estado fica ativado por padrão quando AddInteractiveServerComponents é chamado AddRazorComponents no arquivo Program.
MemoryCache é a implementação de armazenamento padrão para instâncias de aplicativo único e armazena até 1.000 circuitos persistentes por duas horas, que são configuráveis.
Use as opções a seguir para alterar os valores padrão do provedor em memória.
-
PersistedCircuitInMemoryMaxRetained (Espaço reservado
{CIRCUIT COUNT}): o número máximo de circuitos que devem ser mantidos. O padrão é 1.000 circuitos. Por exemplo, use2000para reter o estado por até 2.000 circuitos. -
PersistedCircuitInMemoryRetentionPeriod (espaço reservado
{RETENTION PERIOD}): o período máximo de retenção como um TimeSpan. O padrão é duas horas. Por exemplo, useTimeSpan.FromHours(3)para um período de retenção de três horas.
services.Configure<CircuitOptions>(options =>
{
options.PersistedCircuitInMemoryMaxRetained = {CIRCUIT COUNT};
options.PersistedCircuitInMemoryRetentionPeriod = {RETENTION PERIOD};
});
O armazenamento do estado do componente entre circuitos é criada sobre a API existente PersistentComponentState, que continua a manter o estado para componentes pré-gerados que adotam um modo de renderização interativo. Para obter mais informações, consulte Persistência de estado prerenderizado no ASP.NET CoreBlazor.
[OBSERVAÇÃO] A persistência do estado do componente para a pré-renderização funciona em qualquer modo de renderização interativa, mas a persistência do estado do circuito só funciona no modo de renderização Servidor Interativo.
Anote as propriedades do componente com o [PersistentState] atributo para habilitar a persistência do estado do circuito. O exemplo a seguir também associa os itens com o atributo de diretiva @key para fornecer um identificador exclusivo para cada instância de componente:
@foreach (var item in Items)
{
<ItemDisplay @key="@($"unique-prefix-{item.Id}")" Item="item" />
}
@code {
[PersistentState]
public List<Item> Items { get; set; }
protected override async Task OnInitializedAsync()
{
Items ??= await LoadItemsAsync();
}
}
Para persistir o estado dos serviços escopados, anote as propriedades do serviço com o atributo [PersistentState], adicione o serviço à coleção de serviços e chame o método de extensão RegisterPersistentService com o serviço.
public class CustomUserService
{
[PersistentState]
public string UserData { get; set; }
}
services.AddScoped<CustomUserService>();
services.AddRazorComponents()
.AddInteractiveServerComponents()
.RegisterPersistentService<CustomUserService>(RenderMode.InteractiveAuto);
[OBSERVAÇÃO] O exemplo anterior mantém o estado
UserDataquando o serviço é usado na pré-geração de componentes para a renderização do Interactive Server e do Interactive WebAssembly, porqueRenderMode.InteractiveAutoé atribuído a RegisterPersistentService. No entanto, a persistência do estado do circuito só está disponível para o modo de renderização do Servidor Interativo .
Para lidar com a persistência de estado distribuído (e atuar como o mecanismo de persistência de estado padrão quando configurado), atribua uma HybridCache (API: HybridCache) ao aplicativo, que configura seu próprio período de persistência (PersistedCircuitDistributedRetentionPeriodoito horas por padrão).
HybridCache é usado porque fornece uma abordagem unificada para o armazenamento distribuído que não requer pacotes separados para cada provedor de armazenamento.
No exemplo a seguir, um HybridCache é implementado com o provedor de armazenamento Redis :
services.AddHybridCache()
.AddRedis("{CONNECTION STRING}");
services.AddRazorComponents()
.AddInteractiveServerComponents();
No exemplo anterior, o espaço reservado {CONNECTION STRING} representa a string de conexão do cache Redis, que deve ser fornecida usando uma abordagem segura, como a ferramenta Gerenciador de Segredos no ambiente ou o Azure Key Vault com Identidades Gerenciadas do Azure para aplicativos implantados no Azure em qualquer ambiente.
Pausar e retomar circuitos
Pause e retome circuitos para implementar políticas personalizadas que melhorem a escalabilidade de um aplicativo.
Pausar um circuito armazena detalhes sobre o circuito no armazenamento do navegador do lado do cliente e remove o circuito da memória, o que libera recursos do servidor. Retomar o circuito estabelece um novo circuito e inicializa-o usando o estado persistente.
De um manipulador de eventos JavaScript:
- Chame
Blazor.pausepara pausar um circuito. - Chame
Blazor.resumepara retomar um circuito.
O exemplo a seguir pressupõe que um circuito não é necessário para um aplicativo que não está visível:
window.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') {
Blazor.pause();
} else if (document.visibilityState === 'visible') {
Blazor.resume();
}
});
Persistir o estado entre circuitos
Em geral, mantenha o estado entre circuitos em que os usuários estão criando dados ativamente, não simplesmente lendo dados que já existem.
Para preservar o estado entre circuitos, o aplicativo deve persistir os dados em algum outro local de armazenamento que não seja a memória do servidor. A persistência de estado não é automática. Você deve executar etapas ao desenvolver o aplicativo para implementar a persistência de dados com estado.
A persistência de dados normalmente só é necessária para o estado de alto valor que os usuários se esforçaram para criar. Nos exemplos a seguir, a persistência do estado economiza tempo ou ajuda em atividades comerciais.
- Formulários da Web de várias etapas: demora para um usuário inserir dados novamente em várias etapas concluídas de um formulário da Web de várias etapas, se o estado for perdido. Um usuário perderá o estado nesse cenário, se sair do formulário e retornar mais tarde.
- Carrinhos de compras: qualquer componente comercialmente importante de um aplicativo que representa uma possível receita pode ser mantido. Um usuário que perde o estado e, portanto, o carrinho de compras, pode comprar menos produtos ou serviços quando retornar ao site mais tarde.
Um aplicativo só pode persistir o estado do aplicativo. UIs não podem ser persistidas, como instâncias de componentes e suas árvores de renderização. Os componentes e as árvores de renderização geralmente não são serializáveis. Para persistir o estado da interface do usuário, como os nós expandidos de um controle de exibição de árvore, o aplicativo deve usar o código personalizado para modelar o comportamento do estado da interface do usuário como estado serializável do aplicativo.
Armazenamento do lado do servidor
Para persistência de dados permanente que abrange vários usuários e dispositivos, o aplicativo pode usar o armazenamento do lado do servidor. As opções incluem:
- Armazenamento de Blobs
- Armazenamento de par chave-valor
- Banco de dados relacional
- Armazenamento de tabela
Depois que os dados são salvos, o estado do usuário é retido e disponibilizado em qualquer novo circuito.
Para obter mais informações sobre as opções de armazenamento de dados do Azure, confira o seguinte:
Armazenamento do navegador
Para obter mais informações, consulte ASP.NET Gerenciamento de estado principal Blazor usando o armazenamento do navegador protegido.