Skip to content

Revamp Components Blazor samples + add validate-blazor-feature skill#67497

Draft
javiercn wants to merge 7 commits into
javiercn/create-worktree-skillfrom
javiercn/blazor-canonical-samples
Draft

Revamp Components Blazor samples + add validate-blazor-feature skill#67497
javiercn wants to merge 7 commits into
javiercn/create-worktree-skillfrom
javiercn/blazor-canonical-samples

Conversation

@javiercn

Copy link
Copy Markdown
Member

Summary

Revamps the Blazor samples under src/Components/Samples and src/Components/WebAssembly/Samples into a minimal canonical set that mirrors the dotnet new blazor/blazorwasm template options, and adds a skill (plus its Vally eval) that teaches agents how to validate a Blazor feature against these samples.

The previous samples were an amalgam: a single BlazorUnitedApp wired with pre-.NET 8 conventions, and the deprecated ASP.NET Core hosted WebAssembly model. There was no clean standalone-WASM sample and no global-interactivity sample.

Canonical samples

Generated from the templates with Auto interactivity (the structural superset) and adapted to reference the in-tree framework (<Reference Include="Microsoft.AspNetCore.*">):

  • BlazorWebAppGlobal (+ .Client): global interactivity, InteractiveAuto on <Routes>/<HeadOutlet> in App.razor. Change that one value to InteractiveServer/InteractiveWebAssembly for whole-app Server/WASM.
  • BlazorWebAppPerPage (+ .Client): per-page interactivity. Apply @rendermode per page/component, mix modes, or omit for static SSR.
  • BlazorWebAssemblyStandalone: standalone WebAssembly app (replaces the deprecated HostedBlazorWebassemblyApp).

This covers every interactivity platform (Server/WebAssembly/Auto/None) and location (Global/Per-page) by editing a single @rendermode rather than restructuring projects.

Removes BlazorUnitedApp (+ .Client) and HostedBlazorWebassemblyApp, and updates AspNetCore.slnx, Components.slnf, ComponentsNoDeps.slnf, and src/Components/AGENTS.md.

Validation

All three samples (and their .Client projects) build against the in-tree framework (0 warnings, 0 errors) and were exercised end-to-end in a browser:

Sample Checked Result
BlazorWebAppPerPage Counter InteractiveAuto increments (Server circuit, _blazor WebSocket); Weather async table works, 0 page errors
BlazorWebAppGlobal Counter InteractiveAuto increments works, 0 page errors
BlazorWebAssemblyStandalone WebAssembly runtime boots in-browser; Counter increments works, 0 page errors

validate-blazor-feature skill

.github/skills/validate-blazor-feature/ teaches an agent to validate a Blazor feature/behavior interactively before writing E2E tests:

  • which sample to use and where to add the scenario page (.Client for WebAssembly/Auto, host Components/Pages for Server/static SSR);
  • how to set the render mode (per-page @rendermode vs global @rendermode on Routes/HeadOutlet; omit for static SSR; prerender:false variant);
  • building the in-tree framework + Blazor JS and launching the sample;
  • driving it with the Playwright MCP browser tools and asserting a real state change (rendered markup alone is a false positive, since static SSR emits the same HTML), plus confirming the circuit/WASM attached;
  • references/error-checks.md: a catalog of common build/interactivity/console/WebAssembly failures with symptom -> cause -> fix, and false positives to ignore (stale other-port console errors, blazor.boot.json 404 on current previews).

A Vally eval (eng/skill-evals/validate-blazor-feature/eval.vally.yaml, 5 procedure-knowledge stimuli) plus the generic skills-vs-baseline.experiment.yaml cover the skill. A runs=1 smoke showed the skill flips the two baseline-failing stimuli (WebAssembly page placement, debugging a non-interactive component) to passing and ties the rest.

Copilot AI and others added 7 commits June 30, 2026 22:39
* Initial plan

* Fix hidden property lookup during validation

Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>

* Add generic hidden-property validation regression test

Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>

* Fix emitted GetProperty lookup for hidden members

Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Youssef1313 <31348972+Youssef1313@users.noreply.github.com>
…yMetadata` (#67460)

Aligns CsrfProtectionMiddleware with classic AntiforgeryMiddleware: validation runs only when the matched endpoint has IAntiforgeryMetadata { RequiresValidation: true }. Endpoints without metadata (plain MapPost, plain [HttpPost]) pass through, matching .NET 10 behavior — so no customer endpoint that worked on .NET 10 will start failing on .NET 11.

Blazor SSR and RDF form binding stay protected because they already attach RequireAntiforgeryTokenAttribute automatically. The MiddlewareInvokedKeys.CsrfProtection sentinel is still set unconditionally to preserve the FormFeature backstop contract from #67082.
…root (#67469)

* Avoid recompiling shared framework when publishing to layout root

PublishToSharedLayoutRoot published the shared framework / targeting pack
by invoking arcade's PublishToDisk through a nested <MSBuild> call that
overrode OutputPath. OutputPath is a well-known global property, so the
override forks a new project configuration; resolving the framework file
list under that forked configuration rebuilds the member assemblies a
second time. The second compile deletes and recreates PDBs in a small
window, causing the intermittent MSB3030 'could not copy ... not found'
race that parallel consumers hit (dotnet/msbuild#12927).

Instead, run PublishToSharedLayoutRoot AfterTargets=Build (so the files
are already built and there is no circular dependency) and copy the
already-built FilesToPublish list to the layout root in the same
configuration, mirroring the Copy that arcade's PublishToDisk performs.
This removes the OutputPath fork and the duplicate compile. The
_PublishingToLayout differentiator is no longer needed because we no
longer reuse the OutputPath-differentiated configuration.

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

* Clarify publishing process in Microsoft.AspNetCore.App.Runtime.sfxproj

Update comments to clarify the publishing process for the shared framework.

* Fix NU5118 by capturing layout file list into a private item

Option B ran GetFilesToPublish via DependsOnTargets in the primary
configuration. GetFilesToPublish captures _GetAllSharedFrameworkFiles
into the project-global _FilesToPackage item, which arcade's pack path
(_AddFilesToNuGetPackage) later appends to as well -- doubling every
entry (plain + R2R) and tripping NU5118.

Instead, call _GetAllSharedFrameworkFiles directly and capture its
TargetOutputs into a private item, then replicate arcade's
GetFilesToPublish RuntimePack/TargetingPack transform to compute the
layout destination. This avoids mutating the packaging items while still
reusing the already-built file list (no extra compile).

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revamps src/Components/Samples and src/Components/WebAssembly/Samples with a
minimal canonical set generated from the Blazor templates (dotnet new blazor/
blazorwasm, 11.0.100 preview, Auto interactivity) and adapted to reference the
in-tree framework. Covers the full InteractivityPlatform x Location matrix by
editing a single @rendermode:

- BlazorWebAppGlobal (+ .Client): global interactivity, InteractiveAuto at the
  root. Switch the one @rendermode to Server/WebAssembly for global Server/WASM.
- BlazorWebAppPerPage (+ .Client): per-page interactivity; apply @rendermode per
  page/component, or omit for static SSR.
- BlazorWebAssemblyStandalone: standalone WebAssembly app (replaces the
  deprecated HostedBlazorWebassemblyApp).

Removes BlazorUnitedApp(+.Client) and HostedBlazorWebassemblyApp, and updates
AspNetCore.slnx, Components.slnf, ComponentsNoDeps.slnf, and AGENTS.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Knowledge skill teaching agents to validate a Blazor feature or behavior
interactively with the canonical Components samples and the Playwright MCP
browser tools, before writing E2E tests:
- choosing the sample (per-page / global / standalone) and where to add the
  scenario page (.Client for WebAssembly/Auto, host Components/Pages for
  Server/static SSR);
- setting the render mode (per-page @rendermode vs global @rendermode on
  Routes/HeadOutlet; omit for static SSR; prerender:false variant);
- building the in-tree framework + Blazor JS and launching the sample;
- driving it in a browser and asserting a real state change (not just SSR
  markup) plus confirming the circuit/WASM attached;
- scoping console-error checks and a catalog of common failures, symptoms,
  fixes, and false positives in references/error-checks.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds eng/skill-evals/validate-blazor-feature/eval.vally.yaml (5 procedure-
knowledge stimuli: sample/page placement, switching render mode, confirming
real interactivity vs static SSR, scoping console-error checks, debugging a
non-interactive component) plus the generic skills-vs-baseline.experiment.yaml
that globs every skill eval and loads .github/skills/<skill> via \.

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

None yet

5 participants