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.

C#
@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:

C#
// 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:

C#
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.

C#
// 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 fragmentosNavLinkMatch.All considera apenas o caminho da URL, mantendo o link ativo mesmo que ?pagina=2 ou #ancora variem.
  • 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() e Blazor.resumeCircuit() permitem pausar circuitos quando o usuário muda de aba e retomá‑los ao voltar.
  • Scripts otimizados – os arquivos blazor.web.js e blazor.server.js sã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> e UseStatusCodePagesWithReExecute(...).

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.