Skip to content

[release-notes] ASP.NET Core in .NET 11 Preview 5#10422

Draft
danroth27 wants to merge 6 commits into
release-notes/11.0-preview5from
release-notes/11.0-preview5-aspnetcore
Draft

[release-notes] ASP.NET Core in .NET 11 Preview 5#10422
danroth27 wants to merge 6 commits into
release-notes/11.0-preview5from
release-notes/11.0-preview5-aspnetcore

Conversation

@danroth27
Copy link
Copy Markdown
Member

ASP.NET Core release notes for .NET 11 Preview 5.

This component PR targets the base milestone branch release-notes/11.0-preview5 (umbrella PR: #10421). Review and edit the markdown here in isolation — when this PR merges into the base branch, the changes roll up into the umbrella PR.

Draft generated with the release-notes skill in this repo. Verify feature selection, code samples, API names, and contributor attributions before marking ready for review.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danroth27 danroth27 added area-release-notes automation Created by automated repository workflows/agents. labels May 28, 2026
@danroth27 danroth27 self-assigned this May 28, 2026
@danroth27 danroth27 added area-release-notes automation Created by automated repository workflows/agents. labels May 28, 2026
Copilot AI added 2 commits May 27, 2026 20:11
Hands-on testing with the samples app surfaced two Preview 5 ASP.NET Core features that weren't in the first draft: async form validation (dotnet/aspnetcore #66526) and resource-based validation localization (dotnet/aspnetcore #66646). Both ship together and are foundational for the SSR client validation section, so add dedicated sections covering the EditContext.AddValidationTask / IsValidationPending API and the AddValidationLocalization<T> wire-up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Found via a milestone cross-check sweep against the draft: PR #65650 was
merged into main on 2026-05-14 with labels area-mvc,feature-openapi but no
11.0-preview5 milestone tag, which kept it off the editorial scoring pass's
radar even though it changes user-visible MVC + minimal API + OpenAPI
behavior. Adds a dedicated section under the OpenAPI cluster.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danroth27
Copy link
Copy Markdown
Member Author

@davpetr FYI: Generated ASP.NET Core release notes for .NET 11 Preview 5.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds ASP.NET Core component release notes for .NET 11 Preview 5, fitting into the preview milestone documentation set that rolls up into the umbrella release-notes PR.

Changes:

  • Adds feature highlights for Blazor, QuickGrid, Kestrel, and OpenAPI updates.
  • Adds bug-fix summaries grouped by ASP.NET Core area.
  • Adds community contributor acknowledgements for the milestone.

Comment thread release-notes/11.0/preview/preview5/aspnetcore.md Outdated
Comment thread release-notes/11.0/preview/preview5/aspnetcore.md Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Daniel Roth <daroth@microsoft.com>
Comment thread release-notes/11.0/preview/preview5/aspnetcore.md Outdated
Copy link
Copy Markdown
Contributor

@mikekistler mikekistler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good with my one suggested change. 👍

Comment thread release-notes/11.0/preview/preview5/aspnetcore.md Outdated
Copy link
Copy Markdown
Member

@oroztocil oroztocil left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I posted the re-worked sections as regular comments to avoid problems with code blocks inside suggestion blocks.

Feel free to make the sections shorter if there is too much detail. However, the original texts were confusing and leaking implementation details.

Comment on lines +5 to +7
- [Blazor SSR forms validate in the browser](#blazor-ssr-forms-validate-in-the-browser)
- [Blazor forms support async validation](#blazor-forms-support-async-validation)
- [Validation supports resource-based localization](#validation-supports-resource-based-localization)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- [Blazor SSR forms validate in the browser](#blazor-ssr-forms-validate-in-the-browser)
- [Blazor forms support async validation](#blazor-forms-support-async-validation)
- [Validation supports resource-based localization](#validation-supports-resource-based-localization)
- [Blazor SSR supports client-side validation](#blazor-ssr-supports-client-side-validation)
- [Blazor supports async form validation](#blazor-supports-async-form-validation)
- [Blazor and Minimal APIs support localized validation errors](#blazor-and-minimal-apis-support-error-localization)

Comment on lines +108 to +127
## Validation supports resource-based localization

`Microsoft.Extensions.Validation` now ships with built-in localization that flows through Blazor's `DataAnnotationsValidator` and minimal APIs that opt into the new validation pipeline ([dotnet/aspnetcore #66646](https://github.com/dotnet/aspnetcore/pull/66646)). `AddValidationLocalization<TResource>()` registers an `IValidationLocalizer` that resolves `[Display(Name = ...)]` values and `ValidationAttribute.ErrorMessage` keys against an `IStringLocalizer<TResource>` backed by `.resx` files. The same model produces the same display names and validation messages on the server, in the rendered HTML for client-side validation, and in localized API error responses.

```csharp
builder.Services.AddLocalization();
builder.Services.AddValidation();
builder.Services.AddValidationLocalization<ValidationMessages>();
```

```csharp
[ValidatableType]
public class ContactModel
{
[Required(ErrorMessage = nameof(ValidationMessages.RequiredError))]
[EmailAddress(ErrorMessage = nameof(ValidationMessages.EmailError))]
[Display(Name = nameof(ValidationMessages.ContactEmail))]
public string? Email { get; set; }
}
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blazor and Minimal APIs support error localization

Validation of Blazor forms and Minimal API endpoints gets first-class support for localization of error messages and property names. By default, localization uses language-specific RESX files deployed as part of the assembly.

builder.Services.AddValidation()
    .AddValidationLocalization<ValidationMessages>();
    // Resolves to ValidationMessages.en.resx, ValidationMessages.es.resx, ...
[ValidatableType]
public class ContactModel
{
    // Values of ErrorMessage are used as localization keys.
    [Required(ErrorMessage = "RequiredError")]
    [EmailAddress(ErrorMessage = "EmailError")]
    [Display(Name = "ContactEmail")]
    public string? Email { get; set; }
}

Applications can also register custom IStringLocalizerFactory implementations to read the localized strings from other sources such as databases or JSON files. User registered type takes precedence over the default RESX localization.

builder.Services.AddValidation()
    .AddValidationLocalization();
builder.Services.AddSingleton<IStringLocalizerFactory, DbStringLocalizerFactory>();

Applications can also configure a programmatic strategy for localization, removing the need to specify localization keys on every validation attribute.

builder.Services.AddValidation()
    .AddValidationLocalization<ValidationMessages>(options =>
    {
        options.ErrorMessageKeyProvider = ctx =>
            ctx.Attribute.ErrorMessage ?? $"{ctx.Attribute.GetType().Name}_Error";
    });
[ValidatableType]
public class ContactModel
{
    // Looks-up localized string for 'RequiredAttribute_Error' automatically.
    [Required]
    public string? Username { get; set; }
}

Comment on lines +57 to +106
## Blazor forms support async validation

Blazor forms now support asynchronous validation rules without leaving the `EditContext` model ([dotnet/aspnetcore #66526](https://github.com/dotnet/aspnetcore/pull/66526)). `EditContext.AddValidationTask(FieldIdentifier, Task, CancellationTokenSource)` registers an in-flight check that the framework tracks per field, cancels when superseded, and surfaces through new `IsValidationPending`, `IsValidationFaulted`, and `IsValidationSuperseded` queries. `OnValidationRequestedAsync` lets submit handlers await the same pipeline before reporting overall validity, so async uniqueness, server lookups, and remote calls participate in the standard `ValidationMessageStore`/`ValidationSummary` flow.

```razor
<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>

@code {
[Inject] public UserService Users { get; set; } = default!;

private readonly RegistrationModel model = new();
private EditContext editContext = default!;
private ValidationMessageStore messages = default!;

protected override void OnInitialized()
{
editContext = new EditContext(model);
messages = new ValidationMessageStore(editContext);
editContext.OnFieldChanged += (_, e) =>
{
if (e.FieldIdentifier.FieldName == nameof(model.Username))
{
var cts = new CancellationTokenSource();
editContext.AddValidationTask(e.FieldIdentifier,
CheckAsync(e.FieldIdentifier, model.Username, cts.Token), cts);
}
};
}

private async Task CheckAsync(FieldIdentifier field, string value, CancellationToken ct)
{
messages.Clear(field);
if (await Users.IsUsernameTakenAsync(value, ct))
{
messages.Add(field, "Username is taken.");
}
editContext.NotifyValidationStateChanged();
}

private async Task HandleSubmit() => await editContext.ValidateAsync();
}
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blazor supports async form validation

Blazor forms get support for async validation rules such as database lookups or remote API calls. In any rendering mode, EditForm submit validation now properly awaits async validators end-to-end. In interactive modes, validator components can register per-field async tasks via EditContext.AddValidationTask The framework tracks them, cancels superseded tasks, and exposes progress status via IsValidationPending(field) and IsValidationFaulted(field).

While Preview 5 ships the building blocks for Blazor forms, the full built-in async validation experience will be enabled when the new asynchronous DataAnnotations APIs are released in a later Preview. These APIs will be fully supported by the existing DataAnnotationsValidator component.

<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>

@code {
    [Inject] public UserService Users { get; set; } = default!;

    private readonly RegistrationModel model = new();
    private EditContext editContext = default!;
    private ValidationMessageStore messages = default!;

    protected override void OnInitialized()
    {
        editContext = new EditContext(model);
        messages = new ValidationMessageStore(editContext);
        editContext.OnFieldChanged += (_, e) =>
        {
            if (e.FieldIdentifier.FieldName == nameof(model.Username))
            {
                var cts = new CancellationTokenSource();
                editContext.AddValidationTask(e.FieldIdentifier,
                    CheckAsync(e.FieldIdentifier, model.Username, cts.Token), cts);
            }
        };
    }

    private async Task CheckAsync(FieldIdentifier field, string value, CancellationToken ct)
    {
        messages.Clear(field);
        if (await Users.IsUsernameTakenAsync(value, ct))
        {
            messages.Add(field, "Username is taken.");
        }
        editContext.NotifyValidationStateChanged();
    }

    private async Task HandleSubmit() => await editContext.ValidateAsync();
}

Comment on lines +23 to +55
## Blazor SSR forms validate in the browser

Blazor SSR forms now render client-side validation metadata from `System.ComponentModel.DataAnnotations` attributes and include a small JavaScript validator that reads the generated `data-val-*` attributes ([dotnet/aspnetcore #66441](https://github.com/dotnet/aspnetcore/pull/66441), [dotnet/aspnetcore #66420](https://github.com/dotnet/aspnetcore/pull/66420)). Static SSR forms that already use `DataAnnotationsValidator` can show validation messages before posting back to the server. The .NET model remains the source of truth for validation rules, and the browser gets the same instant feedback pattern used by MVC unobtrusive validation.

```razor
@page "/subscribe"
@using System.ComponentModel.DataAnnotations

<EditForm Model="Model" FormName="subscribe" OnValidSubmit="SubscribeAsync">
<DataAnnotationsValidator />

<label>
Email
<InputText @bind-Value="Model.Email" />
</label>
<ValidationMessage For="() => Model.Email" />

<button type="submit">Subscribe</button>
</EditForm>

@code {
private SubscribeForm Model { get; } = new();

private Task SubscribeAsync() => Task.CompletedTask;

private sealed class SubscribeForm
{
[Required]
[EmailAddress]
public string? Email { get; set; }
}
}
```
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blazor SSR supports client-side validation

Blazor SSR forms now get instant, in-browser validation feedback without a server round-trip, matching the experience provided by interactive Blazor apps and MVC apps with unobtrusive validation. The .NET model remains the single source of truth for validation rules. The server renders metadata for the validation rules which are then enforced by the Blazor JS code on the client-side.

The feature is enabled by default for all SSR forms that include the DataAnnotationsValidator component. Both enhanced and non-enhanced forms are supported.

<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>

    <div>
        <label for="ConfirmPassword">Confirm Password</label>
        <InputText @bind-Value="Model.ConfirmPassword" id="ConfirmPassword" type="password" />
        <ValidationMessage For="@(() => Model.ConfirmPassword)" />
    </div>

    <div>
        <button type="submit" id="submit-btn">Register</button>
    </div>
</EditForm>
public class RegistrationModel
{
    [Required]
    [EmailAddress]
    public string Email { get; set; }

    [Required]
    [StringLength(100, MinimumLength = 8)]
    public string Password { get; set; }

    [Required]
    [Compare("Password")]
    [Display(Name = "Confirm Password")]
    public string ConfirmPassword { get; set; }
}

- Rewrite Blazor validation sections (SSR client-side, async, localization) per @oroztocil's suggestions
- Update TOC entries to match new section titles
- Rewrite #65650 OpenAPI paragraph per @mikekistler's suggestion (and drop the leaked vscode-file URL)
- Remove @cincuranet from community contributors per @Youssef1313 (not a community contributor)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-release-notes automation Created by automated repository workflows/agents.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants