Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Observação
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 10 deste artigo.
Advertência
Esta versão do ASP.NET Core não é mais suportada. 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 .NET 10 deste artigo.
Este artigo descreve abordagens comuns para manter os dados (estado) de um usuário em cenários do lado Blazor do servidor.
Manter o estado do usuário
O Blazor do lado do servidor é um framework de aplicação stateful. Na maioria das vezes, o aplicativo mantém uma conexão com o servidor. O estado do usuário é mantido na memória do servidor em um circuito .
Exemplos de estado do usuário mantido em um circuito incluem:
- A hierarquia de instâncias de componentes e sua 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 mantidos nas instâncias de serviço de injeção de dependência (DI) com escopo para o circuito.
O estado do utilizador também pode ser encontrado em variáveis JavaScript na memória do navegador através de chamadas de interoperabilidade JavaScript.
Se um usuário tiver uma perda temporária de conexão de rede, Blazor tentará reconectá-lo ao circuito original com seu 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 e 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áveis JavaScript definidos por meio de chamadas de interoperabilidade JavaScript são perdidos.
Quando um usuário não pode ser reconectado ao seu circuito original, o usuário recebe um novo circuito com o estado recém-inicializado. Isso equivale a fechar e reabrir um aplicativo da área de trabalho.
Quando persistir o estado do usuário
A persistência do estado não é automática. Você deve tomar medidas ao desenvolver o aplicativo para implementar a persistência de dados com manutenção de estado.
Geralmente, mantenha o estado em circuitos onde os usuários estão ativamente criando dados, 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 gastaram esforço para criar. A persistência do Estado poupa tempo ou ajuda nas atividades comerciais:
- Formulários Web de várias etapas: Consome tempo para o utilizador reinserir dados para várias etapas concluídas de um formulário de várias etapas se o estado deles for perdido. Um utilizador perde o estado nesse cenário se se afastar do formulário e retornar mais tarde.
- Carrinhos de compras: qualquer componente comercialmente importante de um aplicativo que represente receita potencial 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 estado do aplicativo. As interfaces do usuário não podem ser persistentes, como instâncias de componentes e suas árvores de renderização. Componentes e á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 em árvore, o aplicativo deve usar código personalizado para modelar o comportamento do estado da interface do usuário como estado do aplicativo serializável.
Persistência do estado do circuito
Durante a renderização do lado do servidor, Blazor Web Apps pode persistir o estado da sessão (circuito) de um usuário quando a conexão com o servidor é perdida por um longo período de tempo ou pausada proativamente, desde que uma atualização de página inteira não seja acionada. Isso permite que os usuários retomem sua sessão sem perder o trabalho não salvo nos seguintes cenários:
- Limitação de recursos de separadores do navegador
- Utilizadores de dispositivos móveis que mudam de aplicações
- Interrupções na rede
- Gerenciamento proativo de recursos (pausando circuitos inativos)
- Navegação melhorada
Os recursos do servidor podem ser libertados se o estado do circuito puder ser preservado e retomado mais tarde.
- Mesmo se desconectado, um circuito pode continuar a executar 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 precisa acompanhar os componentes do aplicativo e outros objetos do lado do servidor.
O estado é persistente 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 delimitados: Estado armazenado dentro de um serviço do lado do servidor, por exemplo, o utilizador atual.
Condições:
- O recurso só é eficaz para renderização do Servidor Interativo.
- Se o usuário atualizar a página (aplicativo), o estado persistente será perdido.
- O estado deve ser JSON serializável. Referências cíclicas ou entidades ORM podem não serializar corretamente.
- Use
@keypara exclusividade ao renderizar componentes em um loop para evitar conflitos de chave. - Persista apenas o estado necessário. O armazenamento excessivo de dados pode afetar o desempenho.
- Sem hibernação automática. Você deve aceitar e configurar a persistência de estado explicitamente.
- Nenhuma garantia de recuperação. Se a persistência de estado falhar, o aplicativo voltará para a experiência desconectada padrão.
A persistência de estado é ativada por padrão quando AddInteractiveServerComponents é chamada em 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 seguintes opções para alterar os valores padrão do provedor em memória.
-
PersistedCircuitInMemoryMaxRetained
{CIRCUIT COUNT}( espaço reservado): O número máximo de circuitos a reter. O padrão é 1.000 circuitos. Por exemplo, use2000para reter o estado para até 2.000 circuitos. -
PersistedCircuitInMemoryRetentionPeriod
{RETENTION PERIOD}(marcador de posição): O período máximo de retenção como TimeSpan. O padrão é duas horas. Por exemplo, useTimeSpan.FromHours(3)por um período de retenção de três horas.
services.Configure<CircuitOptions>(options =>
{
options.PersistedCircuitInMemoryMaxRetained = {CIRCUIT COUNT};
options.PersistedCircuitInMemoryRetentionPeriod = {RETENTION PERIOD};
});
O estado persistente do componente entre circuitos é construído sobre a API existente PersistentComponentState , que continua a persistir o estado para componentes pré-renderizados que adotam um modo de renderização interativo. Para obter mais informações, consulte Persistência de estado pré-renderizado do núcleo ASP.NETBlazor.
[OBSERVAÇÃO] O estado persistente do componente para pré-renderização funciona para qualquer modo de renderização interativo, mas a persistência do estado do circuito só funciona para o modo de renderização do Servidor Interativo .
Anote as propriedades do componente com o atributo [PersistentState] para habilitar a persistência do estado do circuito. O exemplo a seguir também identifica os itens com o atributo @key directive para fornecer um identificador exclusivo para cada instância do 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 preservar o estado dos serviços com escopo, anote as propriedades do serviço com o [PersistentState] atributo, adicione o serviço à coleção de serviços e utilize 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é-renderização de componentes tanto para renderização no Servidor Interativo quanto no WebAssembly Interativo, porqueRenderMode.InteractiveAutoé definido como 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 para atuar como o mecanismo de persistência de estado padrão quando configurado), atribua um HybridCache (API: HybridCache) ao aplicativo, que configura seu próprio período de persistência (PersistedCircuitDistributedRetentionPeriod, oito 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 {CONNECTION STRING} marcador representa a cadeia de ligação à cache Rederis, que deve ser fornecida usando uma abordagem segura, como a ferramenta Secret Manager no Development ambiente ou o Azure Key Vault com Azure Managed Identities para aplicações implementadas no Azure em qualquer ambiente.
Pausar e retomar circuitos
Pausar e retomar 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, o que libera recursos do servidor. Retomar o circuito estabelece um novo circuito e o inicializa usando o estado persistente.
A partir de um manipulador de eventos JavaScript:
- Chame
Blazor.pausepara pausar um circuito. - Ligue para
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 através de circuitos
Geralmente, mantenha o estado em circuitos onde os usuários estão ativamente criando dados, não simplesmente lendo dados que já existem.
Para preservar o estado entre circuitos, o aplicativo deve manter os dados em algum outro local de armazenamento que não seja a memória do servidor. A persistência do estado não é automática. Você deve tomar medidas ao desenvolver o aplicativo para implementar a persistência de dados com manutenção de estado.
A persistência de dados normalmente só é necessária para o estado de alto valor que os usuários gastaram esforço para criar. Nos exemplos a seguir, o estado persistente economiza tempo ou auxilia em atividades comerciais:
- Formulários Web de várias etapas: Consome tempo para o utilizador reinserir dados para várias etapas concluídas de um formulário de várias etapas se o estado deles for perdido. Um utilizador perde o estado nesse cenário se se afastar do formulário e retornar mais tarde.
- Carrinhos de compras: qualquer componente comercialmente importante de um aplicativo que represente receita potencial 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 estado do aplicativo. As interfaces do usuário não podem ser persistentes, como instâncias de componentes e suas árvores de renderização. Componentes e á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 em árvore, o aplicativo deve usar código personalizado para modelar o comportamento do estado da interface do usuário como estado do aplicativo serializável.
Armazenamento do lado do servidor
Para persistência permanente de dados 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 chave-valor
- Base de dados relacional
- Armazenamento de mesas
Depois que os dados são salvos, o estado do usuário é mantido e disponível em qualquer novo circuito.
Para obter mais informações sobre as opções de armazenamento de dados do Azure, consulte o seguinte:
Armazenamento do navegador
Para obter mais informações, consulte ASP.NET Gerenciamento de estado principal Blazor usando o armazenamento protegido do navegador.