Update .NET 11 Blazor Identity scaffolding - #3836
Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
It spans authentication behavior, generated Identity templates, antiforgery flows, and multiple Blazor render modes across server and client projects.
Pull request overview
Updates .NET 11 Blazor Identity scaffolding to match the Blazor Web App template, including antiforgery, TempData, passkey, validation, email, and render-mode support.
Changes:
- Refreshes Identity templates and generated T4 outputs.
- Adds passkey authenticator metadata and improved form handling.
- Adds server/client authentication wiring, overwrite behavior, and integration coverage.
File summaries
| File | Description |
|---|---|
test/.../ScaffoldCliHelper.cs |
Updates Blazor navigation test structure. |
test/.../Net11TemplateExistenceTests.cs |
Verifies the new authenticator template. |
test/.../AddFileStepTests.cs |
Tests overwrite and existing-file behavior. |
src/.../dotnet-scaffold.csproj |
Registers the new T4 template outputs. |
src/.../PasskeySubmit.razor.js |
Removes manual antiforgery headers. |
src/.../blazorIdentityChanges.json |
Adds render-mode and Identity code modifications. |
src/.../StatusMessage.tt |
Simplifies status message rendering. |
src/.../StatusMessage.cs |
Regenerates status message output. |
src/.../RedirectToLogin.tt |
Removes obsolete namespace usage. |
src/.../RedirectToLogin.cs |
Regenerates redirect output. |
src/.../PasskeySubmit.tt |
Adds formnovalidate and removes token plumbing. |
src/.../PasskeySubmit.cs |
Regenerates passkey submit output. |
src/.../ExternalLoginPicker.tt |
Removes redundant antiforgery markup. |
src/.../ExternalLoginPicker.cs |
Regenerates external login output. |
src/.../PasskeyAuthenticators.tt |
Adds authenticator display-name mapping. |
src/.../PasskeyAuthenticators.Interfaces.cs |
Adds template interface metadata. |
src/.../PasskeyAuthenticators.cs |
Adds generated authenticator helper output. |
src/.../ResetPassword.tt |
Updates validation and display metadata. |
src/.../ResetPassword.cs |
Regenerates reset-password output. |
src/.../ResendEmailConfirmation.tt |
Updates validation summary markup. |
src/.../ResendEmailConfirmation.cs |
Regenerates confirmation output. |
src/.../Register.tt |
Updates registration validation and sign-in checks. |
src/.../Register.cs |
Regenerates registration output. |
src/.../TwoFactorAuthentication.tt |
Migrates status messages to TempData. |
src/.../SetPassword.tt |
Migrates status messages and invalid-user handling. |
src/.../SetPassword.cs |
Regenerates set-password output. |
src/.../ResetAuthenticator.tt |
Migrates status messages and antiforgery handling. |
src/.../ResetAuthenticator.cs |
Regenerates authenticator-reset output. |
src/.../RenamePasskey.tt |
Migrates passkey status handling. |
src/.../RenamePasskey.cs |
Regenerates rename-passkey output. |
src/.../PersonalData.tt |
Updates TempData and download form handling. |
src/.../PersonalData.cs |
Regenerates personal-data output. |
src/.../Passkeys.tt |
Adds authenticator names, dates, and TempData. |
src/.../Index.tt |
Migrates profile status messages. |
src/.../Index.cs |
Regenerates profile output. |
src/.../GenerateRecoveryCodes.tt |
Migrates recovery-code handling. |
src/.../GenerateRecoveryCodes.cs |
Regenerates recovery-code output. |
src/.../ExternalLogins.tt |
Migrates external-login status handling. |
src/.../EnableAuthenticator.tt |
Updates validation and TempData handling. |
src/.../EnableAuthenticator.cs |
Regenerates authenticator output. |
src/.../Email.tt |
Updates email form metadata and status handling. |
src/.../Disable2fa.tt |
Migrates two-factor status handling. |
src/.../Disable2fa.cs |
Regenerates two-factor output. |
src/.../DeletePersonalData.tt |
Updates validation and TempData handling. |
src/.../DeletePersonalData.cs |
Regenerates deletion output. |
src/.../ChangePassword.tt |
Updates password form metadata and status handling. |
src/.../LoginWithRecoveryCode.tt |
Updates validation summary markup. |
src/.../LoginWithRecoveryCode.cs |
Regenerates recovery-login output. |
src/.../LoginWith2fa.tt |
Updates validation and checkbox markup. |
src/.../LoginWith2fa.cs |
Regenerates two-factor login output. |
src/.../Login.tt |
Uses asynchronous validation and display metadata. |
src/.../InvalidUser.tt |
Generates invalid-user messages directly. |
src/.../InvalidUser.cs |
Regenerates invalid-user output. |
src/.../ForgotPassword.tt |
Updates validation and display metadata. |
src/.../ForgotPassword.cs |
Regenerates forgot-password output. |
src/.../ExternalLogin.tt |
Migrates external-login status handling. |
src/.../ConfirmEmailChange.tt |
Migrates confirmation status handling. |
src/.../ConfirmEmailChange.cs |
Regenerates confirmation output. |
src/.../IdentityRedirectManager.tt |
Replaces cookie status flow with TempData support. |
src/.../IdentityRedirectManager.cs |
Regenerates redirect-manager output. |
src/.../IdentityNoOpEmailSender.tt |
Updates confirmation and reset wording. |
src/.../IdentityNoOpEmailSender.cs |
Regenerates email-sender output. |
src/.../IdentityComponentsEndpointRouteBuilderExtensions.tt |
Adds endpoint antiforgery validation. |
src/.../ValidateIdentityStep.cs |
Detects existing Identity and render modes. |
src/.../AddFileStep.cs |
Adds configurable overwrite behavior. |
src/.../BlazorIdentityHelper.cs |
Adds client-project routing and template filtering. |
src/.../ScaffolderBuilderAspNetExtensions.cs |
Skips dependent steps when already configured. |
src/.../BlazorIdentityScaffolderBuilderExtensions.cs |
Adds client wiring, packages, and overwrite support. |
src/.../AspNetCommandService.cs |
Registers the new client scaffolding steps. |
Review details
- Files reviewed: 79/79 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Client discovery rejects valid project formats/locales, and upgrading existing WebAssembly projects can leave conflicting redirect components.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Option filtering regresses existing semantics, legacy redirect components can still cause ambiguous Razor resolution, and required integration coverage remains incomplete.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (3)
Port the framework guard from #3836 using the existing target-framework helper. The passkey script is not available for .NET 8 or 9, so skip its step instead of failing scaffolding now that required-step failures propagate to the process exit code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e
2a6a1ba to
c7ebeb9
Compare
c7ebeb9 to
0a2a979
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Global WebAssembly or Auto projects with a custom client root namespace can generate an invalid Identity layout type reference.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
* Propagate scaffolding failures to CLI exit codes Return required-step failures through the command handler, runner, process entry point, and interactive flow. Preserve skipped and optional steps, report partial-change diagnostics, and add regression coverage. Fixes #3845 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e * Trim exit-code tests to meaningful regression coverage Remove duplicate runner and direct-flow cases, low-value construction and empty-step checks, and redundant logging assertions. Retain process exit-code coverage, step ordering semantics, and built-in and external interactive failure propagation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e * Revert core README changes from exit-code fix Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e * Preserve command failures through interactive flow fallback Cache the command execution result and reuse it when the interactive flow invokes RunAsync after validation failure. Exercise production interactive mode with an isolated Windows console buffer and assert the fallback failure and exactly one execution. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e * Skip Blazor Identity passkey script before .NET 10 Port the framework guard from #3836 using the existing target-framework helper. The passkey script is not available for .NET 8 or 9, so skip its step instead of failing scaffolding now that required-step failures propagate to the process exit code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e * Return portable failure code for interactive flow exceptions Report unexpected interactive flow errors and return 1 instead of int.MinValue, which becomes success on Unix. Cover successful, nonzero, and exception results. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e * Make scaffold exit codes reflect package and tool failures Stop on failed package additions, distinguish matching existing static files from conflicts, propagate tool manager failures, and normalize negative interactive flow results at the common runner boundary. Add focused end-to-end and unit regressions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e --------- Copilot-Session: 71b25d6d-c063-4036-bebc-b34f1487819e
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Flatten template filtering, move invariant calculations outside the loop, and clarify client redirect placement. Strengthen output-path assertions and cover framework-specific provider and redirect decisions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Allow !Option conditions in code-modification recipes and use !InteractiveServer to match the Blazor template's authorization registration. Document and test option matching, update integration assertions, and retain the requested redirect-comment spacing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Use a smaller CSS insertion anchor while preserving template rule order, and convert the .NET 9 recipe to UTF-8. Remove test-only friend access and its dependent tests, restore unrelated README and CLI runner changes, and move MSBuild evaluation details into reference documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Consolidate overwrite coverage, remove overlapping scenarios and cosmetic assertions, and exercise CSS edits through representative fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Separate interactivity and validation scenarios, share project setup, and use ordinary project references in happy-path coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Insert account navigation independently of layout indentation, including apps upgraded from .NET 10, and cover overwrite idempotence in the existing integration case. Align .NET 11 generated C# import ordering, provider namespace syntax, and ApplicationUser spacing with the project templates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Use 11.0.*-* for WebAssembly dependencies in the Identity fixtures, accepting stable and prerelease packages without a point-in-time RC build pin. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Load configuration-relative text fragments with explicit validation. Share navigation CSS and code across .NET 9-11 and navigation markup between the .NET 11 server and client recipes. Include fragments in development and packaged layouts, document their behavior, and cover invalid FileBlock definitions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Use one navigation fragment for .NET 9-11, adding the antiforgery token through ordered logout-form replacements for .NET 9/10. Remove the version-specific fragment packaging rules. Remove RedirectToLogin namespace qualification and unused client namespace plumbing. Retain normal per-page Auto coverage without the legacy component collision fixture. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Include the default RouteView layout attribute so the Identity routing replacement is exercised without the legacy redirect collision setup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Extract the identical PageRenderMode block into a shared FileBlock fragment for .NET 9, 10, and 11 without changing generated content. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Restore the README to its pre-PR content. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Rename BlazorIdentityTestProject to BlazorTestProject, update its callers, and use a generic temporary-directory prefix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Remove the duplicate .NET 8 analysis-failure case and five low-value assertions while retaining focused behavioral coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Insert Identity client service registrations before builder.Build() for .NET 9 through 11, covering separate Build and RunAsync statements in the existing per-page Auto integration case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Cover async login validation, TempData status flow, and passkey display metadata in the existing .NET 11 integration case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Preserve render-mode-aware routing and cascading authentication state. Remove conflicting host edits, hard-coded database fallback, redundant factory registration and duplicate imports; keep migrations middleware development-only. Use realistic integration fixtures and verify generated routing and host configuration, including .NET 8 navigation and Razor code placement. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Include Microsoft.Data.SqlClient.Extensions.Azure for SQL Server projects targeting .NET 11 or later. Cover provider and framework boundaries and exercise SQL Server in the existing .NET 11 CLI integration test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Keep the matching-content and differing-content checks from main, cover explicit overwrite, and remove the obsolete unconditional existing-file success expectation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
Carry RootNamespace alongside the discovered WebAssembly project path and use it for client-hosted layouts. Extend the existing global interactivity cases to cover custom namespaces without adding test cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: a37bc150-e82d-4428-8401-fd90abdc868d
0a2a979 to
7d4cb81
Compare
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
The broad authentication, security, generated-template, and cross-project changes warrant final human review despite strong test coverage and no additional defects found.
Review effort: Balanced
Findings: None
Resolved since last review (1)
phenning
left a comment
There was a problem hiding this comment.
Looks good to me, but would like a final from Hailey, since she is most familiar with the changes here.



Summary
PasskeySubmit.razor.jswith--overwrite.dotnet/aspnetcorerelease/11.0commit5a0e9e1e9a865e8f79fde9cc63bb739f3547c06b.Coverage retained
AcceptsInteractiveRouting().builder.Build().Scope and known limitations
RedirectToLoginname collisions during re-scaffolding are intentionally deferred. Namespace qualification and the legacy-collision fixture were removed during simplification; normal client namespace imports are used.Local validation
00686ef1, 327 selected Identity and affected-helper tests plus 3 MSBuild project-discovery tests passed.CI
Linux jobs have repeatedly exhausted hosted-agent disk space during packaging. Disk-capacity investigation is separate from this PR; this PR does not change pipeline configuration. See the current PR checks for the latest job results.
Closes #3797