evento
Junte-se a nós na FabCon Vegas
31/03, 23 - 2/04, 23
O melhor evento liderado pela comunidade Microsoft Fabric, Power BI, SQL e AI. 31 de março a 2 de abril de 2025.
Registe-se hoje mesmoEste browser já não é suportado.
Atualize para o Microsoft Edge para tirar partido das mais recentes funcionalidades, atualizações de segurança e de suporte técnico.
Nota
Esta não é a versão mais recente deste artigo. Para a versão atual, consulte a versão .NET 9 deste artigo.
Aviso
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 .NET Core. Para a versão atual, consulte a versão .NET 9 deste artigo.
Importante
Estas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.
Para a versão atual, consulte a versão .NET 9 deste artigo.
Este artigo descreve abordagens comuns para manter os dados (estado) de um usuário enquanto ele usa um aplicativo e em sessões do navegador.
Nota
Os exemplos de código neste artigo adotam tipos de referência anuláveis (NRTs) ede análise estática de estado nulo do compilador .NET, que são suportados no ASP.NET Core no .NET 6 ou posterior. Ao direcionar-se para o ASP.NET Core 5.0 ou versões anteriores, remova a designação de tipo nulo (?
) dos tipos nos exemplos do artigo.
O Blazor do lado do servidor é um framework de aplicação com estado. 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:
O estado do usuário também pode ser encontrado em variáveis JavaScript no conjunto de memória do navegador por meio de chamadas de 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:
Quando um usuário não pode ser reconectado ao seu circuito original, o usuário recebe um novo circuito com um estado vazio. Isso equivale a fechar e reabrir um aplicativo da área de trabalho.
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:
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.
Existem locais comuns para o estado persistente:
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:
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:
Para dados transitórios que representam o estado de navegação, modele os dados como parte da URL. Exemplos de estado do usuário modelado na URL incluem:
O conteúdo da barra de endereço do navegador é mantido:
Para obter informações sobre como definir padrões de URL com a diretiva @page
, consulte ASP.NET Core Blazor roteamento e navegação.
Para dados transitórios que o utilizador está a criar ativamente, um local de armazenamento comumente usado são as coleções localStorage
e sessionStorage
no navegador.
localStorage
está limitado ao escopo da instância do navegador. Se o usuário recarregar a página ou fechar e reabrir o navegador, o estado persistirá. Se o usuário abrir várias guias do navegador, o estado será compartilhado entre as guias. Os dados persistem em localStorage
até serem explicitamente apagados. Os dados localStorage
de um documento carregado numa sessão de "navegação privada" ou "anónima" são limpos quando o último separador "privado" é fechado.sessionStorage
tem como escopo a guia do navegador. Se o usuário recarregar a guia, o estado persistirá. Se o usuário fechar a guia ou o navegador, o estado será perdido. Se o usuário abrir várias guias do navegador, cada guia terá sua própria versão independente dos dados.Geralmente, sessionStorage
é mais seguro de usar.
sessionStorage
evita o risco de um utilizador abrir várias abas e encontrar o seguinte:
localStorage
é a melhor opção se a aplicação precisar manter o estado ao fechar e reabrir o navegador.
Advertências para o uso do armazenamento do navegador:
Os pacotes NuGet de terceiros fornecem APIs para trabalhar com localStorage
e sessionStorage
. Vale a pena considerar a escolha de um pacote que use de forma transparente ASP.NET Core Data Protection. A Proteção de Dados encripta os dados armazenados e reduz o risco potencial de adulteração dos dados armazenados. Se os dados serializados por JSON forem armazenados em texto sem formatação, os usuários poderão ver os dados usando as ferramentas de desenvolvedor do navegador e também modificar os dados armazenados. Proteger dados triviais não é um problema. Por exemplo, ler ou modificar a cor armazenada de um elemento da interface do usuário não é um risco de segurança significativo para o usuário ou a organização. Evite permitir que os usuários inspecionem ou adulterem dados confidenciais.
ASP.NET Core Protected Browser Storage aproveita ASP.NET Core Data Protection para localStorage
e sessionStorage
.
Nota
O Armazenamento Protegido do Navegador depende do ASP.NET Core Data Protection e só é suportado para aplicações Blazor do lado do servidor.
Aviso
Microsoft.AspNetCore.ProtectedBrowserStorage
é um pacote experimental sem suporte que não se destina ao uso em produção.
O pacote só está disponível para uso em aplicativos ASP.NET Core 3.1.
Adicione uma referência de pacote a Microsoft.AspNetCore.ProtectedBrowserStorage
.
Nota
Para obter orientação sobre como adicionar pacotes a aplicativos .NET, consulte os artigos em Instalar e gerenciar pacotes em Fluxo de trabalho de consumo de pacotes (documentação do NuGet). Confirme as versões corretas do pacote em NuGet.org.
No arquivo _Host.cshtml
, adicione o seguinte script dentro da etiqueta </body>
de fechamento.
<script src="_content/Microsoft.AspNetCore.ProtectedBrowserStorage/protectedBrowserStorage.js"></script>
No Startup.ConfigureServices
, chame AddProtectedBrowserStorage
para adicionar os serviços localStorage
e sessionStorage
à coleção de serviços:
services.AddProtectedBrowserStorage();
Em qualquer componente que exija o carregamento ou o salvamento de dados no armazenamento do navegador, use a diretiva @inject
para injetar uma instância de um dos seguintes:
ProtectedLocalStorage
ProtectedSessionStorage
A escolha depende do local de armazenamento do navegador que você deseja usar. No exemplo a seguir, sessionStorage
é usado:
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
A diretiva @using
pode ser colocada no arquivo de _Imports.razor
do aplicativo em vez de no componente. O uso do arquivo _Imports.razor
torna o namespace disponível para segmentos maiores do aplicativo ou do aplicativo inteiro.
Para persistir o valor currentCount
no componente Counter
de um aplicativo com base no modelo de projeto Blazor, modifique o método IncrementCount
para usar ProtectedSessionStore.SetAsync
:
private async Task IncrementCount()
{
currentCount++;
await ProtectedSessionStore.SetAsync("count", currentCount);
}
Em aplicativos maiores e mais realistas, o armazenamento de campos individuais é um cenário improvável. Os aplicativos são mais propensos a armazenar objetos de modelo inteiros que incluem estado complexo.
ProtectedSessionStore
serializa e desserializa automaticamente dados JSON para armazenar objetos de estado complexos.
No exemplo de código anterior, os dados currentCount
são armazenados como sessionStorage['count']
no navegador do usuário. Os dados não são armazenados em texto simples, mas são protegidos usando ASP.NET Proteção de Dados Principais. Os dados criptografados podem ser inspecionados se sessionStorage['count']
for avaliado no console do desenvolvedor do navegador.
Para recuperar os dados currentCount
se o usuário retornar ao componente Counter
mais tarde, inclusive se o usuário estiver em um novo circuito, use ProtectedSessionStore.GetAsync
:
protected override async Task OnInitializedAsync()
{
var result = await ProtectedSessionStore.GetAsync<int>("count");
currentCount = result.Success ? result.Value : 0;
}
protected override async Task OnInitializedAsync()
{
currentCount = await ProtectedSessionStore.GetAsync<int>("count");
}
Se os parâmetros do componente incluírem o estado de navegação, chame ProtectedSessionStore.GetAsync
e atribua um resultado nãonull
em OnParametersSetAsync, não OnInitializedAsync.
OnInitializedAsync só é chamado uma vez quando o componente é instanciado pela primeira vez.
OnInitializedAsync não será chamado novamente mais tarde se o usuário navegar para um URL diferente enquanto permanece na mesma página. Para obter mais informações, consulte ASP.NETde ciclo de vida do componente Core Razor .
Aviso
Os exemplos nesta seção só funcionam se o servidor não tiver a pré-renderização habilitada. Com a pré-renderização ativada, um erro é gerado explicando que as chamadas de interoperabilidade JavaScript não podem ser emitidas porque o componente está sendo pré-renderizado.
Desative a pré-renderização ou adicione código adicional para trabalhar com a pré-renderização. Para saber mais sobre como escrever código que funciona com a pré-renderização, consulte a seção Manipular pré-renderização.
Como o armazenamento do navegador é acessado de forma assíncrona por meio de uma conexão de rede, sempre há um período de tempo antes que os dados sejam carregados e estejam disponíveis para um componente. Para obter os melhores resultados, renderize uma mensagem enquanto o carregamento está em andamento em vez de exibir dados em branco ou padrão.
Uma abordagem é controlar se os dados estão null
, o que significa que os dados ainda estão sendo carregados. No componente Counter
padrão, a contagem é mantida em um int
.
Torne currentCount
anulável adicionando um ponto de interrogação (?
) ao tipo (int
):
private int? currentCount;
Em vez de exibir incondicionalmente o botão de contagem e Increment
, exiba esses elementos somente se os dados forem carregados verificando HasValue:
@if (currentCount.HasValue)
{
<p>Current count: <strong>@currentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
}
else
{
<p>Loading...</p>
}
Durante a pré-renderização:
localStorage
ou sessionStorage
não estão disponíveis durante a pré-renderização. Se o componente tentar interagir com o armazenamento, um erro será gerado explicando que as chamadas de interoperabilidade JavaScript não podem ser emitidas porque o componente está sendo pré-renderizado.
Uma maneira de resolver o erro é desativar a pré-renderização. Essa geralmente é a melhor escolha se o aplicativo fizer uso intenso do armazenamento baseado em navegador. A pré-renderização adiciona complexidade e não beneficia o aplicativo porque o aplicativo não pode pré-renderizar nenhum conteúdo útil até que localStorage
ou sessionStorage
estejam disponíveis.
Para desativar a pré-renderização, indique o modo de renderização com o parâmetro prerender
definido como false
no componente de nível mais alto na hierarquia de componentes do aplicativo que não seja um componente raiz.
Nota
Não há suporte para tornar um componente raiz interativo, como o componente App
. Portanto, a pré-renderização não pode ser desabilitada diretamente pelo componente App
.
Para aplicativos baseados no modelo de projeto Blazor Web App, a pré-renderização normalmente é desabilitada quando o componente Routes
é usado no componente App
(Components/App.razor
):
<Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Além disso, desative a pré-renderização para o componente HeadOutlet
:
<HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
Para obter mais informações, consulte modos de renderização do ASP.NET Core Blazor.
Para desativar a pré-renderização, abra o arquivo
<component type="typeof(App)" render-mode="Server" />
Quando a pré-renderização está desativada, pré-renderização de <head>
conteúdo está desabilitada.
A pré-renderização pode ser útil para outras páginas que não usam localStorage
ou sessionStorage
. Para manter a pré-renderização, adie a operação de carregamento até que o navegador esteja conectado ao circuito. Segue-se um exemplo para armazenar um valor de contador:
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedLocalStorage ProtectedLocalStore
@if (isConnected)
{
<p>Current count: <strong>@currentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
}
else
{
<p>Loading...</p>
}
@code {
private int currentCount;
private bool isConnected;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isConnected = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
var result = await ProtectedLocalStore.GetAsync<int>("count");
currentCount = result.Success ? result.Value : 0;
}
private async Task IncrementCount()
{
currentCount++;
await ProtectedLocalStore.SetAsync("count", currentCount);
}
}
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@inject ProtectedLocalStorage ProtectedLocalStore
@if (isConnected)
{
<p>Current count: <strong>@currentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
}
else
{
<p>Loading...</p>
}
@code {
private int currentCount = 0;
private bool isConnected = false;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isConnected = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
currentCount = await ProtectedLocalStore.GetAsync<int>("count");
}
private async Task IncrementCount()
{
currentCount++;
await ProtectedLocalStore.SetAsync("count", currentCount);
}
}
Se muitos componentes dependem de armazenamento baseado em navegador, a implementação do código do provedor de estado muitas vezes cria duplicação de código. Uma opção para evitar a duplicação de código é criar um componente pai do provedor de estado que encapsula a lógica do provedor de estado. Os componentes filho podem trabalhar com dados persistentes sem se preocupar com o mecanismo de persistência de estado.
No exemplo a seguir de um componente CounterStateProvider
, os dados do contador são persistidos em sessionStorage
, e ele lida com a fase de carregamento ao não renderizar o conteúdo filho até que o carregamento de estado esteja concluído.
O componente CounterStateProvider
gere a pré-renderização ao não carregar o estado até após a renderização do componente no método de ciclo de vida OnAfterRenderAsync
, que não é executado durante a pré-renderização.
A abordagem nesta seção não é capaz de acionar a rerenderização de vários componentes inscritos na mesma página. Se um componente inscrito alterar o estado, ele será renderizado novamente e poderá exibir o estado atualizado, mas um componente diferente na mesma página exibindo esse estado exibirá dados obsoletos até sua próxima rerenderização. Portanto, a abordagem descrita nesta seção é mais adequada para usar o estado em um único componente na página.
CounterStateProvider.razor
:
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@if (isLoaded)
{
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
}
else
{
<p>Loading...</p>
}
@code {
private bool isLoaded;
[Parameter]
public RenderFragment? ChildContent { get; set; }
public int CurrentCount { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isLoaded = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
var result = await ProtectedSessionStore.GetAsync<int>("count");
CurrentCount = result.Success ? result.Value : 0;
isLoaded = true;
}
public async Task IncrementCount()
{
CurrentCount++;
await ProtectedSessionStore.SetAsync("count", CurrentCount);
}
}
@using Microsoft.AspNetCore.ProtectedBrowserStorage
@inject ProtectedSessionStorage ProtectedSessionStore
@if (isLoaded)
{
<CascadingValue Value="this">
@ChildContent
</CascadingValue>
}
else
{
<p>Loading...</p>
}
@code {
private bool isLoaded;
[Parameter]
public RenderFragment ChildContent { get; set; }
public int CurrentCount { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
isLoaded = true;
await LoadStateAsync();
StateHasChanged();
}
}
private async Task LoadStateAsync()
{
CurrentCount = await ProtectedSessionStore.GetAsync<int>("count");
isLoaded = true;
}
public async Task IncrementCount()
{
CurrentCount++;
await ProtectedSessionStore.SetAsync("count", CurrentCount);
}
}
Nota
Para obter mais informações sobre RenderFragment, consulte componentes do ASP.NET Core Razor.
Para tornar o estado acessível a todos os componentes em um aplicativo, envolva o componente CounterStateProvider
em torno do Router (<Router>...</Router>
) no componente Routes
com renderização interativa global do lado do servidor (SSR interativo).
No componente App
(Components/App.razor
):
<Routes @rendermode="InteractiveServer" />
No componente Routes
(Components/Routes.razor
):
Para usar o componente CounterStateProvider
, envolva uma instância do componente em torno de qualquer outro componente que exija acesso ao estado do contador. Para tornar o estado acessível a todos os componentes de um aplicativo, envolva o componente CounterStateProvider
ao redor do Router no componente App
(App.razor
):
<CounterStateProvider>
<Router ...>
...
</Router>
</CounterStateProvider>
Nota
Com o lançamento do ASP.NET Core 5.0.1 e para quaisquer versões adicionais do 5.x, o componente Router
inclui o parâmetro PreferExactMatches
definido como @true
. Para obter mais informações, consulte migrar do ASP.NET Core 3.1 para o 5.0.
Os componentes encapsulados recebem e podem modificar o estado do contador persistente. O seguinte componente Counter
implementa o padrão:
@page "/counter"
<p>Current count: <strong>@CounterStateProvider?.CurrentCount</strong></p>
<button @onclick="IncrementCount">Increment</button>
@code {
[CascadingParameter]
private CounterStateProvider? CounterStateProvider { get; set; }
private async Task IncrementCount()
{
if (CounterStateProvider is not null)
{
await CounterStateProvider.IncrementCount();
}
}
}
O componente anterior não é necessário para interagir com ProtectedBrowserStorage
, nem lida com uma fase de "carregamento".
Em geral, recomenda-se o padrão do componente pai do provedor de estado :
Para persistir muitos objetos de estado diferentes e consumir subconjuntos diferentes de objetos em locais diferentes, é melhor evitar a persistência do estado globalmente.
O estado do usuário criado em um aplicativo Blazor WebAssembly é mantido na memória do navegador.
Exemplos de estado do usuário mantido na memória do navegador incluem:
Quando um usuário fecha e reabre o navegador ou recarrega a página, o estado do usuário mantido na memória do navegador é perdido.
Nota
Protected Browser Storage (namespaceMicrosoft.AspNetCore.Components.Server.ProtectedBrowserStorage) depende do ASP.NET Core Data Protection e só é suportado para aplicativos Blazor do lado do servidor.
Geralmente, mantenha o estado nas sessões do navegador em que os usuários estão ativamente criando dados, não simplesmente lendo dados que já existem.
Para preservar o estado nas sessões do navegador, o aplicativo deve manter os dados em algum outro local de armazenamento que não a memória do navegador. 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 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:
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 UI, como os nós expandidos de um controlo de visualização em árvore, a aplicação deve usar código personalizado para modelar o comportamento do estado da UI como estado da aplicação serializável.
Existem locais comuns para o estado persistente:
Para persistência permanente de dados que abrange vários usuários e dispositivos, o aplicativo pode usar armazenamento independente do lado do servidor acessado por meio de uma API da Web. As opções incluem:
Depois que os dados são salvos, o estado do usuário é mantido e fica disponível em qualquer nova sessão do navegador.
Como Blazor WebAssembly aplicativos são executados inteiramente no navegador do usuário, eles exigem medidas adicionais para acessar sistemas externos seguros, como serviços de armazenamento e bancos de dados.
Blazor WebAssembly aplicativos são protegidos da mesma maneira que os aplicativos de página única (SPAs). Normalmente, um aplicativo autentica um usuário por meio de
Para obter mais informações, consulte os seguintes recursos:
Para obter mais informações sobre as opções de armazenamento de dados do Azure, consulte o seguinte:
Para dados transitórios que representam o estado de navegação, modele os dados como parte da URL. Exemplos de estado do usuário modelado na URL incluem:
O conteúdo da barra de endereço do navegador é mantido se o usuário recarregar manualmente a página.
Para obter informações sobre como definir padrões de URL com a diretiva @page
, consulte ASP.NET Core Blazor roteamento e navegação.
Para dados transitórios que o utilizador está a criar ativamente, uma localização de armazenamento comumente usada é as coleções localStorage
e sessionStorage
do navegador.
localStorage
tem como escopo a instância do navegador. Se o usuário recarregar a página ou fechar e reabrir o navegador, o estado persistirá. Se o utilizador abrir várias abas do navegador, o estado será partilhado entre as abas. Os dados persistem em localStorage
até serem explicitamente eliminados. Os dados localStorage
de um documento carregado numa sessão de "navegação privada" ou "anónima" são limpos quando o último separador "privado" é fechado.sessionStorage
tem como escopo a guia do navegador. Se o usuário recarregar a guia, o estado persistirá. Se o utilizador fechar a guia ou o navegador, o estado será perdido. Se o usuário abrir várias guias do navegador, cada guia terá sua própria versão independente dos dados.Nota
localStorage
e sessionStorage
podem ser usados em aplicativos Blazor WebAssembly, mas apenas escrevendo código personalizado ou usando um pacote de terceiros.
Geralmente, sessionStorage
é mais seguro de usar.
sessionStorage
evita o risco de um utilizador abrir várias abas e encontrar o seguinte:
localStorage
é a melhor escolha se o aplicativo precisar manter o estado mesmo após o navegador ser fechado e reaberto.
Aviso
Os usuários podem visualizar ou adulterar os dados armazenados em localStorage
e sessionStorage
.
Os componentes aninhados normalmente ligam dados usando de ligação encadeada, conforme descrito em ASP.NETde vinculação de dados do Core Blazor . Os componentes aninhados e não aninhados podem compartilhar o acesso aos dados usando um contêiner de estado na memória registrado. Uma classe de contêiner de estado personalizado pode usar um Action atribuível para notificar componentes em diferentes partes do aplicativo sobre alterações de estado. No exemplo a seguir:
Importante
O exemplo nesta seção demonstra como criar um serviço de contêiner de estado na memória, registrar o serviço e usar o serviço em componentes. O exemplo não armazena dados sem um desenvolvimento adicional. Para armazenamento persistente de dados, o contêiner de estado deve adotar um mecanismo de armazenamento subjacente que sobreviva quando a memória do navegador é limpa. Isso pode ser feito com localStorage
/sessionStorage
ou alguma outra tecnologia.
StateContainer.cs
:
public class StateContainer
{
private string? savedString;
public string Property
{
get => savedString ?? string.Empty;
set
{
savedString = value;
NotifyStateChanged();
}
}
public event Action? OnChange;
private void NotifyStateChanged() => OnChange?.Invoke();
}
Aplicativos do lado do cliente (arquivoProgram
):
builder.Services.AddSingleton<StateContainer>();
Aplicativos do lado do servidor (arquivoProgram
, ASP.NET Core no .NET 6 ou posterior):
builder.Services.AddScoped<StateContainer>();
Aplicativos do lado do servidor (Startup.ConfigureServices
de Startup.cs
, ASP.NET Core anteriores à 6.0):
services.AddScoped<StateContainer>();
Shared/Nested.razor
:
@implements IDisposable
@inject StateContainer StateContainer
<h2>Nested component</h2>
<p>Nested component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the Nested component
</button>
</p>
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property =
$"New value set in the Nested component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
StateContainerExample.razor
:
@page "/state-container-example"
@implements IDisposable
@inject StateContainer StateContainer
<h1>State Container Example component</h1>
<p>State Container component Property: <b>@StateContainer.Property</b></p>
<p>
<button @onclick="ChangePropertyValue">
Change the Property from the State Container Example component
</button>
</p>
<Nested />
@code {
protected override void OnInitialized()
{
StateContainer.OnChange += StateHasChanged;
}
private void ChangePropertyValue()
{
StateContainer.Property = "New value set in the State " +
$"Container Example component: {DateTime.Now}";
}
public void Dispose()
{
StateContainer.OnChange -= StateHasChanged;
}
}
Os componentes anteriores implementam IDisposable, e os delegados associados ao OnChange
são desinscritos nos métodos Dispose
, que são chamados pelo framework quando os componentes são eliminados. Para obter mais informações, consulte ASP.NETde ciclo de vida do componente Core Razor .
Ao implementar o armazenamento de estado personalizado, uma abordagem útil é adotar valores e parâmetros em cascata:
Ao usar um serviço de gestão de estado personalizado em que deseja suportar modificação de estado a partir de fora do contexto síncrono do Blazor(por exemplo, a partir de um temporizador ou de um serviço em segundo plano), todos os componentes consumidores devem envolver a chamada StateHasChanged em ComponentBase.InvokeAsync. Isso garante que a notificação de alteração seja tratada no contexto de sincronização do renderizador.
Quando o serviço de gerenciamento de estado não chama StateHasChanged no contexto de sincronização do Blazor, o seguinte erro é lançado:
System.InvalidOperationException: 'O thread atual não está associado ao Dispatcher. Use InvokeAsync() para mudar a execução para o Dispatcher ao ativar a renderização ou o estado do componente.
Para obter mais informações e um exemplo de como resolver este erro, consulte ASP.NET Core Razor de renderização de componentes.
Comentários do ASP.NET Core
O ASP.NET Core é um projeto código aberto. Selecione um link para fornecer comentários:
evento
Junte-se a nós na FabCon Vegas
31/03, 23 - 2/04, 23
O melhor evento liderado pela comunidade Microsoft Fabric, Power BI, SQL e AI. 31 de março a 2 de abril de 2025.
Registe-se hoje mesmoFormação
Módulo
Interaja com dados em aplicativos Web Blazor - Training
Saiba como criar uma interface gráfica do usuário em um aplicativo Web Blazor criando e montando componentes Blazor. Aceda aos dados e partilhe-os para apresentação em várias páginas da sua aplicação.