
ASP.NET Core 11 has no single feature that fundamentally changes how web applications are built. That is not a criticism. Mature frameworks improve by removing custom infrastructure, tightening defaults and making common behavior cheaper or easier to observe.
The changes available through Preview 7 can be ranked by what they can break or simplify in a real application:
| Area | Operational relevance | First check |
|---|---|---|
| Async validation | Removes sync-over-async workarounds | Dependency cost and cancellation |
| OpenAPI 3.2 | Changes the generated contract | Every downstream generator and gateway |
| Native HTTP telemetry | Changes span attributes | Duplicate spans, tags and dashboard queries |
| Request hardening | Rejects more invalid traffic correctly | Proxy and protocol regression tests |
| SignalR auth refresh | Keeps long-lived identity current | Permission loss after refresh |
| Blazor SSR and circuit lifecycle | Avoids rendering and retained server state | Cache isolation and memory under hidden tabs |
| C# unions | Improves contract modeling | Preview and ecosystem compatibility |
Release status: This assessment reflects .NET 11 Preview 7 from August 2026. APIs and defaults can still change before the supported release. Preview builds are useful for finding migration problems, not as a production target.
Async validation solves a real pipeline gap
Data Annotations are synchronous, but many validation rules need I/O. Blocking on a database or service call inside a synchronous attribute wastes threads and ignores cancellation. Repeating the same check in every endpoint scatters one policy across handlers.
.NET 11 introduces AsyncValidationAttribute and IAsyncValidatableObject. ASP.NET Core integrates them through Microsoft.Extensions.Validation for Minimal APIs and Blazor.
1using System.ComponentModel.DataAnnotations;
2using Microsoft.Extensions.DependencyInjection;
3
4public interface ICustomerDirectory
5{
6 Task<bool> EmailExistsAsync(
7 string email,
8 CancellationToken cancellationToken);
9}
10
11public sealed class UniqueEmailAttribute : AsyncValidationAttribute
12{
13 protected override ValidationResult? IsValid(
14 object? value,
15 ValidationContext validationContext)
16 {
17 throw new InvalidOperationException(
18 "UniqueEmailAttribute requires asynchronous validation.");
19 }
20
21 protected override async Task<ValidationResult?> IsValidAsync(
22 object? value,
23 ValidationContext validationContext,
24 CancellationToken cancellationToken)
25 {
26 if (value is not string email)
27 {
28 return ValidationResult.Success;
29 }
30
31 ICustomerDirectory customerDirectory =
32 validationContext.GetRequiredService<ICustomerDirectory>();
33
34 bool exists = await customerDirectory.EmailExistsAsync(
35 email,
36 cancellationToken);
37
38 return exists
39 ? new ValidationResult("The email address is already registered.")
40 : ValidationResult.Success;
41 }
42}
43
44public sealed record CreateCustomerRequest(
45 [property: Required]
46 [property: EmailAddress]
47 [property: UniqueEmail]
48 string Email);
Registration stays small:
1WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
2
3builder.Services.AddValidation();
4builder.Services.AddScoped<ICustomerDirectory, CustomerDirectory>();
Validation still needs a strict budget. A request model with several remote validators can create fan-out before the endpoint starts. Every dependency needs cancellation and a short timeout and collection validation must not execute one query per item.
An async uniqueness check also remains advisory. Another request can insert the same value between validation and persistence. The database constraint is authoritative; validation only improves the error path.
OpenAPI 3.2 is a compatibility change
ASP.NET Core now generates OpenAPI 3.2 by default. The new vocabulary is useful, especially for streams, but the document is consumed by SDK generators, gateways, documentation portals, scanners and contract tests. Those tools will not all adopt 3.2 together.
The default-version change should be treated like any other public contract migration. If one required tool is not ready, pinning 3.1 temporarily is a valid compatibility decision:
1using Microsoft.OpenApi;
2
3WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
4
5builder.Services.AddOpenApi(options =>
6{
7 options.OpenApiVersion = OpenApiSpecVersion.OpenApi3_1;
8});
9
10WebApplication app = builder.Build();
11
12app.MapOpenApi();
13app.Run();
The best 3.2 improvement is a more accurate Server-Sent Events contract. An SSE response can describe the schema of each event instead of appearing as one opaque string:
1using System.Net.ServerSentEvents;
2using System.Runtime.CompilerServices;
3
4app.MapGet(
5 "/orders/stream",
6 (CancellationToken cancellationToken) =>
7 TypedResults.ServerSentEvents(StreamOrdersAsync(cancellationToken)));
8
9static async IAsyncEnumerable<SseItem<OrderStatus>> StreamOrdersAsync(
10 [EnumeratorCancellation] CancellationToken cancellationToken)
11{
12 OrderStatus[] updates =
13 [
14 new OrderStatus("order-42", "accepted"),
15 new OrderStatus("order-42", "processing"),
16 new OrderStatus("order-42", "completed")
17 ];
18
19 foreach (OrderStatus update in updates)
20 {
21 yield return new SseItem<OrderStatus>(update)
22 {
23 EventId = $"{update.OrderId}:{update.State}"
24 };
25
26 await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
27 }
28}
29
30public sealed record OrderStatus(
31 string OrderId,
32 string State);
TypedResults.ServerSentEvents matters here. Returning the enumerable directly follows normal JSON serialization and does not select the SSE result path.
Native telemetry changes the baseline
ASP.NET Core 11 adds OpenTelemetry HTTP semantic-convention attributes to the framework’s server activity. Fields such as http.request.method, url.path, http.response.status_code and server.address can now originate from the framework itself.
1using OpenTelemetry.Trace;
2
3builder.Services
4 .AddOpenTelemetry()
5 .WithTracing(tracing =>
6 {
7 tracing.AddSource("Microsoft.AspNetCore");
8 tracing.AddOtlpExporter();
9 });
OpenTelemetry.Instrumentation.AspNetCore should not be removed immediately after retargeting. The package may still provide behavior beyond the new built-in attributes or be configured through a distribution package.
The migration check should compare traces from the same requests before and after the upgrade:
- duplicate spans or attributes;
- renamed span fields;
- changed status and route values;
- new high-cardinality data;
- broken dashboard and alert queries; and
- changed sampling or export cost.
A semantically better tag is still an operational breaking change when production queries depend on the old name.
Security work mostly arrives through better defaults
Preview 7 narrows automatic unsafe cross-origin request protection to endpoints carrying antiforgery metadata. Form-binding endpoints participate; a normal JSON MapPost does not suddenly require an antiforgery token.
Migration tests should cover that distinction explicitly: same-origin form posts, rejected cross-origin form posts, legitimate non-browser clients and plain JSON APIs.
Authorization metadata also becomes consistent across MVC, SignalR, AuthorizeView and AuthorizeRouteView. Applications with custom IAuthorizationRequirementData attributes should run the same requirement tests across those surfaces rather than assuming identical composition.
Kestrel and middleware now reject more malformed content lengths, invalid connection-specific headers, fragmented trailers, multipart headers, chunked requests and rewrite targets correctly. Malformed HTTP/1.1 parsing also uses a cheaper non-throwing path.
Most applications need no new code for these fixes. They need representative proxy and protocol tests. A reverse proxy depending on invalid behavior is still a migration problem even when Kestrel is correct to reject it.
SignalR authentication can outlive one token
A SignalR connection may remain open longer than the token used during negotiation. ASP.NET Core 11 can refresh authentication without dropping the hub connection:
1using System.Security.Claims;
2using Microsoft.AspNetCore.SignalR;
3
4app.MapHub<OperationsHub>("/operations", options =>
5{
6 options.CloseOnAuthenticationExpiration = true;
7 options.EnableAuthenticationRefresh = true;
8 options.OnAuthenticationRefresh = context =>
9 ValueTask.FromResult(true);
10});
11
12public sealed class OperationsHub : Hub
13{
14 public override Task OnAuthenticationRefreshedAsync()
15 {
16 ClaimsPrincipal? refreshedUser = Context.User;
17 return Task.CompletedTask;
18 }
19}
The client must also request refreshes, either explicitly or through its authentication-refresh configuration and supply fresh credentials. Enabling the server option alone does not renew tokens. The SignalR authentication guide documents both sides of the protocol.
Refreshing identity is only half the feature. If the new principal lost permission, existing group membership and subscriptions may now be wrong. The application must remove access, reject future calls or close the connection. That transition requires an explicit test.
Regular hub invocations can also propagate client cancellation to a server method:
1public sealed class OperationsHub : Hub
2{
3 public async Task RebuildProjectionAsync(
4 CancellationToken cancellationToken)
5 {
6 await ProjectionRebuilder.RebuildAsync(cancellationToken);
7 }
8}
Cancellation remains cooperative. Downstream work must observe the token and a canceled invocation must not leave a transaction half committed.
Zstandard is useful after measurement
Zstandard joins the existing response-compression and request-decompression middleware:
1WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
2
3builder.Services.AddResponseCompression();
4builder.Services.AddRequestDecompression();
5
6WebApplication app = builder.Build();
7
8app.UseResponseCompression();
9app.UseRequestDecompression();
The algorithm often gives service-to-service traffic a good ratio for its CPU cost. Payload size, content type, quality level, proxy behavior and actual client support should still be measured before broad adoption.
Request decompression deserves the stricter review. A small compressed body can expand into substantial memory and CPU work. The framework caps the Zstandard window, but application request-size limits, authentication and timeouts remain necessary.
Response compression now consistently emits Vary: Accept-Encoding, including uncompressed responses. That prevents shared caches from confusing representations.
Blazor 11 is mainly about doing less
The Blazor release contains many features. The useful direction is simpler: keep more pages statically rendered, avoid rebuilding expensive fragments and release inactive circuit resources.
Static SSR forms gain client-side validation while the server remains authoritative. QuickGrid can sort and paginate through URL-driven enhanced forms without requiring an interactive circuit. Avoiding an unnecessary render mode reduces client payload, server state, reconnect behavior and operational complexity.
CacheView skips component execution
CacheView caches rendered HTML for an SSR component subtree. On a hit, child components are not constructed or rendered:
1<CacheView ExpiresAfter="TimeSpan.FromMinutes(5)"
2 VaryByRoute="productId"
3 VaryByQuery="page,pageSize"
4 VaryByCulture="true">
5 <ProductSummary ProductId="productId" />
6</CacheView>
That is more valuable than only caching response transfer. It is also a data-isolation boundary. Tenant, user, culture, feature flags, pricing context and experiments may all affect the HTML. Every missing variation dimension risks serving the wrong content.
ASP.NET Core can require VaryByUser for components such as AuthorizeView, but application-specific context still needs explicit keys and tests.
Server circuits can pause
Interactive Server can pause inactive circuits, allowing hidden tabs to release server resources. The following configuration requires the Microsoft.AspNetCore.Components.Server.AutoPause package at a version matching the ASP.NET Core preview:
1app.MapRazorComponents<App>()
2 .AddInteractiveServerRenderMode()
3 .WithBrowserOptions(options =>
4 {
5 options.AddAutoPause(pauseOptions =>
6 {
7 pauseOptions.Enabled = true;
8 pauseOptions.HiddenDelay = TimeSpan.FromMinutes(2);
9 });
10 });
The browser avoids automatic pauses while inputs are modified, media or transfers are active or circuit work is still running. Relevant measurements include memory, pause success, restore latency, expired state and behavior during deployments. Request throughput alone says little about a server holding thousands of inactive circuits.
The new ASP.NET Core-based Blazor WebAssembly Gateway also replaces the old development server. It provides SPA fallback and YARP proxying for same-origin local development. It reduces CORS friction but does not define the production topology; authentication, TLS, forwarded headers and proxy limits remain application decisions.
C# unions are promising, not yet a contract foundation
Preview 7 can represent C# unions across ASP.NET Core JSON, Minimal APIs, MVC, SignalR, Blazor state and OpenAPI. This sample requires the matching .NET 11 preview SDK and <LangVersion>preview</LangVersion>:
1app.MapPost(
2 "/payments",
3 (PaymentMethod paymentMethod) =>
4 TypedResults.Accepted());
5
6public sealed record CardPayment(
7 string LastFourDigits);
8
9public sealed record BankTransfer(
10 string Iban);
11
12public union PaymentMethod(
13 CardPayment,
14 BankTransfer);
This can replace hand-written discriminator hierarchies. It should still remain outside a long-lived public API today: the language feature is preview, binding is JSON-only, SignalR requires its JSON protocol and third-party generators may not understand the resulting anyOf schema.
That makes unions an excellent prototype and compatibility-test target, not a stable wire-format decision yet.
Smaller changes for the upgrade branch
- Replace obsolete
EditContext.Validatecalls withValidateAsync. - Rename
WebApplicationFactory.ConfigureHostApplicationBuilderoverrides toConfigureWebApplicationBuilder. - Remove dependencies on deleted MVC compatibility APIs.
- Replace the deprecated Blazor WebAssembly DevServer.
- Remove
Microsoft.AspNetCore.Grpc.Swagger, which no longer exists. - Test encoded
/behavior in unusual request targets.
These are not architectural features, but several can stop compilation or integration tests immediately.
Evaluation sequence
- Retarget one representative service in an isolated branch.
- Resolve compiler and analyzer changes without broad suppressions.
- Run every OpenAPI consumer against the generated 3.2 document.
- Compare request traces, dashboards and telemetry cost.
- Exercise form endpoints from same-origin, cross-origin and non-browser clients.
- Load-test async validators with slow dependencies and large invalid payloads.
- Test SignalR token refresh, permission loss, redirects and cancellation.
- Measure Blazor cache isolation and circuit memory under realistic tab activity.
- Review the final breaking-change documentation before production rollout.
What actually matters
The strongest ASP.NET Core 11 changes make existing boundaries more honest. Async validation acknowledges I/O without hiding a blocking call. OpenAPI describes modern contracts more accurately. Native telemetry reduces framework gaps. SignalR identity can remain current. Blazor can avoid work instead of making every interaction expensive.
The release should not be measured by its number of new APIs. Its value lies in how much custom infrastructure can be deleted, which contracts become more accurate and whether applications behave better under real traffic. On that basis, ASP.NET Core 11 is useful, but it belongs in an integration branch long before a production deployment.
For a focused treatment of the framework’s API error contract, see Problem Details in ASP.NET Core and .NET 11.
The detailed source for this snapshot is the .NET 11 Preview 7 announcement and the ASP.NET Core Preview 7 component release notes . Earlier changes are collected in the .NET 11 release notes .
Related articles

Sep 07, 2026 - 10 min read
Migrating Semantic Kernel Agents to Microsoft Agent Framework
Microsoft Agent Framework is the successor to the agent capabilities in Semantic Kernel and AutoGen. That statement is easy to misread as …

Aug 31, 2026 - 22 min read
Building Production MCP Servers with ASP.NET Core
An MCP server can look deceptively small. A package is installed, a method receives an attribute and ASP.NET Core maps an endpoint. That is …

Aug 24, 2026 - 18 min read
Telemetry, Logging and Auditing in .NET: Designing the Right Data Path
Telemetry, logging and auditing are often implemented through the same API because all three produce timestamped records. That similarity is …
Let's Work Together
Looking for an experienced Platform Architect or Engineer for your next project? Whether it's cloud migration, platform modernization or building new solutions from scratch - I'm here to help you succeed.
