Nos últimos meses, a Microsoft lançou o .NET 10, uma versão LTS (suporte longo) que será mantida até novembro de 2028. O ASP.NET Core 10.0 vem nessa esteira e traz recursos pensados para quem constrói APIs e aplicações web interativas com Blazor. Se você usa C#, prepare‑se: há novidades que simplificam validação de dados e que deixam seus aplicativos mais resilientes e rápidos.
Estado persistente no Blazor
Quem já testou prerenderização com Blazor Web Server sabia o problema do “piscar”: a página é pré‑renderizada no servidor, mas assim que o cliente baixa o script interativo o estado some e os dados são carregados novamente. Isso gera requisições duplicadas e uma experiência ruim. No ASP.NET Core 10 isso mudou com o atributo [PersistentState].
Ao marcar propriedades com esse atributo, o Blazor serializa o valor na saída HTML e o reutiliza no momento em que o aplicativo fica interativo. Também persiste o estado quando o usuário perde a conexão e retorna, evitando perder a ordem de uma lista ou a página de um grid.
@page "/contatos"
@inject HttpClient Http
@code {
[PersistentState] public List<Contact>? Contacts { get; set; }
protected override async Task OnInitializedAsync()
{
// Se Contacts for nulo, busca dados; caso contrário usa o valor preservado
Contacts ??= await Http.GetFromJsonAsync<List<Contact>>("api/contatos");
}
}
O resultado é uma renderização sem “flash” e metade das requisições ao servidor. Se a conexão cair, os dados voltam exatamente de onde pararam.
Validações mais simples no Blazor
Suporte a tipos aninhados
Até a versão 9 era preciso validar propriedade por propriedade de um formulário; objetos complexos ou listas não eram analisados. Agora basta chamar builder.Services.AddValidation() no Program.cs e anotar a classe raiz com [ValidatableType] para que o Blazor percorra tipos aninhados e coleções automaticamente:
// Program.cs
builder.Services.AddValidation();
public record Address(string Street, string City, string PostalCode);
[ValidatableType] // habilita validação recursiva
public class Customer
{
[Required] public string Name { get; set; } = "";
public Address? Address { get; set; }
public List<Order> Orders { get; set; } = new();
}
Ao usar <EditForm> e <ValidationSummary>, os erros de campos aninhados aparecem automaticamente.
Validações no nível da classe
Você pode criar atributos de validação que se aplicam à classe inteira, o que possibilita regras que envolvem várias propriedades. No exemplo abaixo, o atributo NoBot herda de ValidationAttribute e verifica se o campo escondido Honeypot está vazio (recurso antispam). Basta colocar [NoBot] na sua classe para que o Blazor invoque a lógica:
public class NoBotAttribute : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value, ValidationContext context)
{
var user = value as UserRegistration;
return string.IsNullOrEmpty(user?.Honeypot)
? ValidationResult.Success
: new ValidationResult("Bot submission detected.");
}
}
[NoBot]
public class UserRegistration
{
public string Name { get; set; } = "";
[EmailAddress]
public string Email { get; set; } = "";
// Campo escondido que bots preenchem
public string? Honeypot { get; set; }
}
Validações integradas em Minimal APIs
Não é apenas o Blazor que recebeu carinho. As Minimal APIs agora suportam validação automática de parâmetros de query, header ou corpo via Data Annotations. Adicione builder.Services.AddValidation() e o framework gera um filter que valida instâncias usadas nos delegados. Entradas inválidas resultam em 400 Bad Request com detalhes, dispensando if manual. Há ainda um comportamento sutil: campos vazios de formulários são convertidos para null para tipos anuláveis, evitando erros de bind.
// Program.cs
builder.Services.AddValidation();
app.MapPost("/customers", (Customer customer) =>
{
// A requisição só chega aqui se 'customer' for válido
SaveToDatabase(customer);
return Results.Created($"/customers/{customer.Id}", customer);
});
// Método de exemplo
void SaveToDatabase(Customer customer)
{
// Simula persistência
}
// Para desativar validação em um endpoint específico:
app.MapPost("/no-validation", (SampleObject obj) =>
{
/* ... */
})
.DisableValidation();
Outras novidades do Blazor
- Links ativos ignoram query strings e fragmentos –
NavLinkMatch.Allconsidera apenas o caminho da URL, mantendo o link ativo mesmo que?pagina=2ou#ancoravariem. - Janela de reconexão customizável – o componente
<ReconnectModal />substitui a modal padrão de “tentando reconectar” e permite estilizar ou traduzir o conteúdo. - Controle do circuito de conexão – novas funções JavaScript
Blazor.pauseCircuit()eBlazor.resumeCircuit()permitem pausar circuitos quando o usuário muda de aba e retomá‑los ao voltar. - Scripts otimizados – os arquivos
blazor.web.jseblazor.server.jssão servidos como static web assets com compressão e fingerprint. Os nomes contém um hash para cache busting e o tamanho fica ~76% menor. - Métricas de instrumentação – novas métricas OpenTelemetry expõem eventos como reconexão e atualização de parâmetros de componentes.
- Navegação suave – chamar
NavigationManager.NavigateTo()com a mesma página e parâmetros não reinicia mais o scroll; o framework também facilita lidar com páginas 404 via<NotFound>eUseStatusCodePagesWithReExecute(...).
Conclusão e próximos passos
O ASP.NET Core 10.0 chegou com foco em produtividade e experiência. O atributo [PersistentState] elimina o incômodo efeito de flash, enquanto a validação recursiva e as anotações ao nível de classe reduzem a quantidade de código repetitivo em formulários. Minimal APIs ganharam filtros de validação automáticos, e outras melhorias como reconexão customizável, scripts otimizados e novas métricas mostram que o ecossistema está maduro.
Experimente habilitar AddValidation() no seu Program.cs, marque propriedades com [PersistentState] e brinque com o <ReconnectModal />. Seu código vai ficar mais limpo e sua aplicação pronta para as demandas da web em 2026 e além.