ASP.NET no .NET 11 Preview 5: novidades e melhorias
O ASP.NET no .NET 11 ganhou um pacote robusto de novidades com o Preview 5, lançado em junho de 2026, e a maior parte delas mira o Blazor. Além disso, a versão traz ajustes no Kestrel, na geração de documentos OpenAPI e uma série de correções reportadas pela comunidade.
Neste artigo, você vai ver cada novidade com exemplos de código e o impacto prático de cada mudança. Por isso, vale ler com o editor aberto e testar os trechos em um projeto de estudo.
O que muda no ASP.NET no .NET 11 Preview 5
O Preview 5 concentra suas entregas em quatro frentes: formulários, gerenciamento de estado, interoperabilidade entre modos de renderização e infraestrutura para aplicações WebAssembly. Em outras palavras, o time da Microsoft atacou pontos que incomodavam quem trabalha com renderização mista.
Na prática, o ASP.NET no .NET 11 caminha para reduzir as diferenças entre o Blazor estático e o Blazor interativo. Assim, recursos que antes exigiam um circuito SignalR ou o runtime WebAssembly passam a funcionar também em páginas renderizadas no servidor.
Vale lembrar que se trata de uma versão preview. Portanto, nomes de APIs e comportamentos ainda podem mudar até o lançamento final, como de fato aconteceu com algumas APIs citadas aqui.
A documentação oficial reúne tudo em What's new in ASP.NET Core in .NET 11, que a Microsoft atualiza a cada preview.
Validação de formulários no Blazor
A validação de formulários recebeu três melhorias no ASP.NET no .NET 11 Preview 5. Primeiro, a validação no cliente para SSR, em seguida a validação assíncrona e, por fim, a localização das mensagens de erro.
Validação client-side no Blazor SSR
Uma das adições mais esperadas para formulários Blazor em modo SSR (Static Server-Side Rendering) é a validação nativa no lado do cliente. Com isso, o usuário recebe retorno sem precisar de um round-trip ao servidor.
Antes, formulários renderizados de forma estática só validavam os dados depois do envio. Dessa forma, a experiência ficava inferior à do MVC com unobtrusive validation ou à dos componentes Blazor interativos.
Agora, formulários SSR que usam o componente DataAnnotationsValidator fornecem feedback instantâneo no navegador. O servidor renderiza os metadados das regras, e o JavaScript do Blazor aplica essas regras no cliente.
Assim, o modelo .NET continua como a única fonte de verdade para as regras de negócio. O recurso vem ativo por padrão em todos os formulários SSR com DataAnnotationsValidator, tanto enhanced quanto não enhanced.
<EditForm Model="Model" Enhance FormName="registration" OnValidSubmit="HandleValidSubmit">
<DataAnnotationsValidator />
<div>
<label for="Email">Email</label>
<InputText @bind-Value="Model!.Email" id="Email" />
<ValidationMessage For="@(() => Model!.Email)" />
</div>
<div>
<label for="Password">Password</label>
<InputText @bind-Value="Model!.Password" id="Password" type="password" />
<ValidationMessage For="@(() => Model!.Password)" />
</div>
<button type="submit" id="submit-btn">Register</button>
</EditForm>
O modelo de dados permanece idêntico ao do modo interativo, com Data Annotations convencionais. Ou seja, você não precisa duplicar regras em JavaScript para ter validação imediata.
Contudo, a validação no cliente não substitui a validação no servidor. Ela melhora a experiência, enquanto o servidor continua responsável pela segurança dos dados.
Validação assíncrona no ASP.NET do .NET 11
O Preview 5 também introduz suporte a validações assíncronas em formulários Blazor. Por exemplo, você pode consultar o banco de dados ou chamar uma API externa para verificar se um nome de usuário está disponível.
Em qualquer modo de renderização, a validação no submit do EditForm agora aguarda a conclusão dos validadores assíncronos. Já nos modos interativos, componentes validadores registram tarefas assíncronas por campo via EditContext.AddValidationTask.
O framework rastreia essas tarefas e cancela execuções que ficaram obsoletas. Além disso, ele expõe o progresso com IsValidationPending(field) e IsValidationFaulted(field).
<EditForm EditContext="editContext" OnSubmit="HandleSubmit">
<InputText @bind-Value="model.Username" />
@if (editContext.IsValidationPending(() => model.Username))
{
<span>Checking availability...</span>
}
<ValidationMessage For="() => model.Username" />
<button type="submit">Register</button>
</EditForm>
Vale destacar que o Preview 5 entrega apenas os blocos de construção da validação assíncrona. A experiência completa com DataAnnotationsValidator depende das novas APIs assíncronas de DataAnnotations, previstas para um preview posterior.
De fato, a documentação atual mostra que essas APIs chegaram depois como AsyncValidationAttribute e IAsyncValidatableObject. Em versões mais recentes, o registro por campo também passou a usar EditContext.RegisterAsyncFieldValidator, então confira o nome da API na versão que você instalou.
Localização de erros de validação
No ASP.NET no .NET 11, formulários Blazor e endpoints de Minimal API agora contam com suporte de primeira classe para localizar mensagens de erro e nomes de propriedades. Por padrão, a localização usa arquivos RESX por idioma, implantados junto com o assembly da aplicação.
builder.Services.AddValidation()
.AddValidationLocalization<ValidationMessages>();
// Resolve para ValidationMessages.en.resx, ValidationMessages.pt-BR.resx, ...
Os valores de ErrorMessage nos atributos de validação funcionam como chaves de localização. Assim, o texto exibido vem do arquivo de recursos do idioma ativo.
[ValidatableType]
public class ContactModel
{
[Required(ErrorMessage = "RequiredField")]
[EmailAddress(ErrorMessage = "InvalidEmail")]
[Display(Name = "ContactEmail")]
public string? Email { get; set; }
}
A plataforma também aceita implementações customizadas de IStringLocalizerFactory. Dessa forma, você pode ler as mensagens de um banco de dados ou de arquivos JSON, e a implementação registrada pelo usuário tem precedência sobre o RESX padrão.
Também dá para definir uma estratégia programática, sem repetir chaves em cada atributo:
builder.Services.AddValidation()
.AddValidationLocalization<ValidationMessages>(options =>
{
// Usa o ErrorMessage como chave ou gera uma chave pelo nome do atributo
options.ErrorMessageKeyProvider = ctx =>
ctx.Attribute.ErrorMessage ?? $"{ctx.Attribute.GetType().Name}_Error";
});
Essa abordagem ajuda em projetos com dezenas de modelos, porque centraliza as chaves e facilita a inclusão de novos idiomas. Ainda assim, a documentação atual indica que versões posteriores tornaram a localização nativa, ativada com AddLocalization seguido de AddValidation.
QuickGrid sem interatividade no ASP.NET do .NET 11
O componente QuickGrid recebeu uma atualização importante no ASP.NET no .NET 11: ordenação e paginação agora funcionam em páginas Blazor SSR estáticas. Antes, esses recursos exigiam um modo interativo.
Quando o grid não está em modo interativo, os controles de ordenação e o paginador viram links que atualizam o estado pela query string da URL. Portanto, o componente deixa de depender de handlers @onclick.
@page "/orders"
@using Microsoft.AspNetCore.Components.QuickGrid
<QuickGrid Items="orders.AsQueryable()" Pagination="pagination">
<PropertyColumn Property="@(o => o.Id)" Sortable="true" />
<PropertyColumn Property="@(o => o.Customer)" Sortable="true" />
<PropertyColumn Property="@(o => o.Total)" Sortable="true" />
</QuickGrid>
<Paginator State="pagination" />
@code {
private readonly PaginationState pagination = new() { ItemsPerPage = 20 };
private readonly List<Order> orders = OrderRepository.GetOrders();
}
O comportamento baseado em URL vem ativo por padrão. Segundo a documentação, a URL passa a carregar parâmetros como page, sort e direction, o que permite compartilhar links e usar os botões de voltar e avançar do navegador.
Para restaurar o comportamento anterior baseado em <button>, basta definir o switch Microsoft.AspNetCore.Components.QuickGrid.EnableUrlBasedQuickGridNavigationAndSorting como false.
// Volta a renderizar <button> com @onclick (exige modo interativo)
AppContext.SetSwitch(
"Microsoft.AspNetCore.Components.QuickGrid.EnableUrlBasedQuickGridNavigationAndSorting",
false);
Atenção ao CSS, porque o elemento renderizado muda de <button> para <a>. Nesse caso, seletores como button.col-title também precisam cobrir a.col-title.
Cultura e estado de sessão no Blazor
No ASP.NET no .NET 11, duas novidades tratam de estado: uma preserva a cultura entre servidor e cliente, enquanto a outra leva a sessão HTTP para dentro dos componentes.
Blazor WebAssembly preserva a cultura do servidor
Aplicações Blazor WebAssembly com pré-renderização no servidor agora persistem o CurrentCulture e o CurrentUICulture no estado do componente. Em seguida, o cliente aplica esses valores antes de carregar os assemblies satélite.
O recurso vem ativo por padrão para componentes WebAssembly interativos. Com isso, a página pré-renderizada e a versão hidratada no cliente usam a mesma cultura.
Se a sua aplicação precisa que o cliente escolha a cultura de forma independente, basta desativar o comportamento:
builder.Services.AddRazorComponents()
.AddInteractiveWebAssemblyComponents(options =>
{
// O cliente passa a escolher a própria cultura
options.UseCultureFromServer = false;
});
Essa mudança elimina um problema visual comum. Antes, a página aparecia com a formatação do servidor e depois mudava para a do cliente, afetando datas, moedas e outros dados regionais.
SupplyParameterFromSession para Blazor SSR
O atributo [SupplyParameterFromSession] chega ao Blazor SSR com o mesmo padrão declarativo de [SupplyParameterFromQuery] e [SupplyParameterFromForm]. Assim, propriedades de componentes leem e gravam valores da sessão HTTP diretamente.
Na prática, você mantém estado de sessão, como o ID de um carrinho ou o progresso de um formulário em etapas, perto do componente que o usa. O framework serializa os valores com System.Text.Json e grava tudo de volta antes de enviar a resposta.
@page "/checkout"
<p>Current step: @CurrentStep</p>
<EditForm Model="Input" FormName="checkout" OnSubmit="NextStep">
<button type="submit">Next</button>
</EditForm>
@code {
// Valor lido e gravado na sessão HTTP com a chave "checkout-step"
[SupplyParameterFromSession(Name = "checkout-step")]
public int CurrentStep { get; set; }
private object Input { get; } = new();
private void NextStep() => CurrentStep++;
}
Para habilitar o recurso, registre os serviços no Program.cs e inclua o middleware de sessão no pipeline:
builder.Services.AddDistributedMemoryCache();
builder.Services.AddSession();
builder.Services.AddRazorComponents();
var app = builder.Build();
app.UseSession();
Diferente do TempData, os valores de sessão não somem depois da leitura. Eles permanecem disponíveis durante todo o tempo de vida da sessão.
Blazor WebAssembly Gateway no ASP.NET do .NET 11
Aplicações Blazor WebAssembly standalone ganharam um novo servidor de desenvolvimento no ASP.NET no .NET 11. O Microsoft.AspNetCore.Components.Gateway é um host ASP.NET Core leve que substitui o pacote Microsoft.AspNetCore.Components.WebAssembly.DevServer.
Segundo a Microsoft, o Gateway serve aplicações tanto em desenvolvimento quanto em produção. Além disso, ele oferece uma infraestrutura mais robusta e integrada do que a ferramenta anterior.
Como se trata de um host ASP.NET Core completo, o fallback SPA para rotas client-side é nativo. Ou seja, requisições que não correspondem a um arquivo estático caem no index.html.
Por isso, rotas como /orders/42 funcionam no refresh do navegador e na navegação direta. Antes, esse cenário exigia configuração extra no servidor que hospedava os arquivos.
Para adotar o Gateway em um projeto existente, a mudança no arquivo de projeto é mínima:
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="11.0.0-preview.5.26302.115" />
<PackageReference Include="Microsoft.AspNetCore.Components.Gateway" Version="11.0.0-preview.5.26302.115" PrivateAssets="all" />
</ItemGroup>
Novos projetos criados com o template atualizado já incluem o Gateway por padrão. Além disso, a documentação explica que a propriedade inspectUri do launchSettings.json deixa de ser necessária com o novo servidor.
ChildContent entre limites de render mode
Componentes renderizados com @rendermode agora aceitam ChildContent e outros parâmetros RenderFragment não genéricos vindos de outro modo de renderização. Antes, essa combinação lançava uma InvalidOperationException.
O erro acontecia porque RenderFragment é um delegate e não atravessava a fronteira entre SSR e interativo. Agora, o Blazor pré-renderiza o fragmento no servidor, captura a árvore resultante e a reidrata dentro do componente filho interativo.
<MyComponent @rendermode="InteractiveServer">
<p>This content is rendered as SSR and projected into the interactive component.</p>
</MyComponent>
Essa melhoria do ASP.NET no .NET 11 amplia a flexibilidade de aplicações com modos de renderização mistos. Por outro lado, fragmentos genéricos ainda têm limitações de serialização neste preview.
Kestrel e OpenAPI no ASP.NET do .NET 11
Fora do Blazor, o ASP.NET no .NET 11 Preview 5 também traz ajustes de segurança no Kestrel e correções na geração de documentos OpenAPI.
Timeout para trailer headers no Kestrel
O Kestrel agora aplica o RequestHeadersTimeout a trailer headers fragmentados de HTTP/2 e HTTP/3 que não concluem o envio do bloco. Assim, o mesmo timeout que protege os headers iniciais passa a cobrir também os frames HEADERS de trailer.
builder.WebHost.ConfigureKestrel(options =>
{
// Também vale para trailer headers incompletos em HTTP/2 e HTTP/3
options.Limits.RequestHeadersTimeout = TimeSpan.FromSeconds(10);
});
Essa melhoria importa em ambientes de alta concorrência. Afinal, conexões abertas de forma maliciosa ou por bugs em clientes poderiam consumir recursos do servidor indefinidamente.
Melhorias nos schemas OpenAPI
A geração de documentos OpenAPI do ASP.NET no .NET 11 recebeu duas correções importantes. Primeiro, parâmetros enum que não vêm do corpo mantêm os nomes originais dos membros C#, mesmo com uma política de nomenclatura no JsonStringEnumConverter.
Isso acontece porque a vinculação de query, route, header e form usa Enum.TryParse, e não a serialização JSON. Em segundo lugar, os identificadores de schemas de arrays agora usam nomes válidos, como stringArray e TodoArray.
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.Converters.Add(
new JsonStringEnumConverter(JsonNamingPolicy.KebabCaseLower));
});
app.MapGet("/orders", (OrderStatus status) => Results.Ok(status));
Com essa configuração, o schema do corpo descreve OrderStatus.PendingReview como pending-review. Enquanto isso, o schema do parâmetro de query descreve o valor aceito como PendingReview.
Endpoints de Minimal API também passam a suportar múltiplos Produces<T>() para o mesmo status code. Por exemplo, uma resposta 200 pode chegar como application/json ou text/plain, cada uma com seu schema.
O mesmo suporte vale para controllers MVC com múltiplos atributos [ProducesResponseType]. Antes, o framework mantinha um único tipo por status code e descartava os demais em silêncio.
Correções de bugs no ASP.NET do .NET 11
O ASP.NET no .NET 11 Preview 5 inclui correções que merecem destaque. No Blazor, o time corrigiu uma falha ao renderizar um componente interativo a partir de um layout durante a navegação enhanced.
Também entraram anotações StringSyntaxAttribute.DateTimeFormat que faltavam nos overloads de formato DateTimeOffset do BindConverter. Assim, o editor passa a reconhecer essas strings como formatos de data.
Em Data Protection e antiforgery, a equipe resolveu a starvation do thread pool durante a inicialização a frio no KeyRingProvider. O problema surgia quando muitos chamadores pediam chaves antes de o key ring estar em cache.
No Kestrel, mensagens HTTP/2 e HTTP/3 com campos de header específicos de conexão agora contam como malformadas, conforme os RFCs 9113 e 9114. Além disso, o servidor fecha a conexão depois de processar uma requisição com Content-Length e Transfer-Encoding juntos, como exige o RFC 9112.
Em Minimal APIs, parâmetros de query do tipo struct opcional não anulável com = default deixaram de lançar exceção. Por fim, application/problem+json e application/problem+xml continuam como tipos preferidos quando o ProducesAttribute também define um tipo de conteúdo.
Se você quer entender melhor esse formato de erro, o artigo sobre ProblemDetails e a RFC 9457 explica o contrato em detalhes.
Como testar o ASP.NET no .NET 11 Preview 5
Para experimentar o ASP.NET no .NET 11 Preview 5, instale o SDK de preview correspondente e crie um projeto separado. Dessa forma, você evita misturar a versão preview com aplicações que rodam em produção.
Uma boa prática é fixar a versão do SDK com um arquivo global.json na pasta do projeto de testes. Assim, os outros projetos da máquina continuam usando a versão estável.
# Confere quais SDKs estão instalados
dotnet --list-sdks
# Cria um Blazor Web App para testar as novidades
dotnet new blazor -o PreviewLab
Em seguida, teste um recurso por vez, como a validação client-side ou o QuickGrid em SSR. Com isso, fica mais fácil identificar o que mudou e reportar problemas no repositório dotnet/aspnetcore.
Para acompanhar a evolução das próximas versões, vale ler também a análise do ASP.NET Core no .NET 11 Preview 7. Lá você vê como várias dessas APIs amadureceram.
Conclusão
O ASP.NET no .NET 11 Preview 5 mostra que a Microsoft segue investindo em um desenvolvimento web mais produtivo, seguro e expressivo. As melhorias no Blazor pesam especialmente para equipes que combinam componentes SSR e interativos na mesma aplicação.
No ASP.NET no .NET 11, a validação client-side em SSR elimina uma diferença notável entre os modos de renderização. Enquanto isso, a validação assíncrona e a localização de erros atendem demandas antigas da comunidade.
O novo Gateway e a passagem de ChildContent entre render modes mostram a maturidade crescente da plataforma. Também preparam o terreno para os recursos finais que chegam nas próximas previews.
Para quem usa ASP.NET Core em produção, acompanhar essas previews ajuda no planejamento de migrações. Portanto, teste cedo, registre o que quebra e adote os novos padrões com calma.
FAQ
O que é o Blazor SSR e como ele difere do Blazor interativo?
O Blazor SSR renderiza os componentes no servidor e entrega HTML pronto, sem conexão SignalR ou runtime WebAssembly. Já o modo interativo mantém um canal de comunicação ou executa código no cliente, o que permite reatividade sem recarregar a página.
A validação client-side no SSR elimina a validação no servidor?
Não. A validação no cliente melhora a experiência, enquanto a validação no servidor continua como fonte de verdade para a segurança.
O [SupplyParameterFromSession] funciona com todos os modos de renderização?
O atributo é específico do Blazor SSR e segue o mesmo escopo de [SupplyParameterFromQuery] e [SupplyParameterFromForm].
O Blazor WebAssembly Gateway pode ser usado em produção?
Sim. O Gateway substitui o DevServer em desenvolvimento e em produção, porque é um host ASP.NET Core completo com fallback SPA nativo.
As melhorias do QuickGrid exigem mudanças no código existente?
Não, porque o comportamento baseado em URL vem ativo por padrão. Quem quiser o comportamento anterior só precisa configurar o switch de contexto correspondente.
A passagem de ChildContent entre render modes funciona com qualquer RenderFragment?
No Preview 5, o suporte cobre ChildContent e outros RenderFragment não genéricos. Fragmentos genéricos ainda têm limitações de serialização.
As melhorias de OpenAPI afetam produção ou só desenvolvimento?
Elas afetam a geração do documento OpenAPI em qualquer ambiente onde ela esteja habilitada, embora seja mais comum usá-la em desenvolvimento e staging.