The CLI now has a dedicated semantic pattern catalog that runs after the normal markup and code-behind transforms. This gives recurring page-shape rewrites a bounded place to live without turning the flat transform list into a giant procedural migration pass.
Use this catalog for patterns that are more than syntax cleanup:
- query-driven detail pages
- action or redirect-only pages
- simple account and auth forms
- master/content contract normalization
The migration pipeline now has three relevant phases for page output:
- Markup transforms make the
.aspx,.ascx, or.masterfile syntactically safe for Blazor/BWFC output. - Code-behind transforms normalize the paired
.csfile enough to expose the migration surface. - Semantic pattern catalog inspects the combined result and applies higher-level rewrites where the page matches a known Web Forms shape.
This means a semantic pattern always sees the post-transform state, not raw Web Forms source.
Each catalog entry implements ISemanticPattern:
public interface ISemanticPattern
{
string Id { get; }
int Order { get; }
SemanticPatternMatch Match(SemanticPatternContext context);
SemanticPatternResult Apply(SemanticPatternContext context);
}The important rules are:
Idmust be stable so diagnostics and tests can target it.Ordercontrols deterministic execution within the catalog.Match()should be lightweight and evidence-driven.Apply()can rewrite markup, code-behind, or both.
SemanticPatternContext gives a pattern the information it needs for a bounded rewrite:
MigrationContextSourceFileFileMetadata- current
Markup - optional
CodeBehind MigrationReport
Patterns should prefer evidence from the transformed markup/code-behind already in the context rather than reparsing the original project through side channels.
When a pattern applies:
- the catalog updates
metadata.MarkupContentandmetadata.CodeBehindContent - the pipeline log records the applied pattern ID and detail text
MigrationReport.SemanticPatternsAppliedis incremented
Patterns should emit a clear detail string that explains why the match happened or what contract was normalized. If a pattern can only do a partial rewrite safely, it should preserve a runnable output shape and leave explicit manual guidance in the emitted content or report.
The first four catalog entries are:
| Order | Pattern | Purpose |
|---|---|---|
| 100 | QueryDetailsSemanticPattern |
Normalize query-string-driven detail pages toward SSR query-bound output |
| 200 | MasterContentContractsSemanticPattern |
Keep generated master/content pairs on the valid MasterPage / Content / ContentPlaceHolder contract |
| 300 | ActionPagesSemanticPattern |
Normalize redirect and action-only pages into usable SSR handler shapes |
| 400 | AccountPagesSemanticPattern |
Convert simple account/login/register forms to SSR-safe form output with explicit auth TODO boundaries |
Add a new catalog entry when all of these are true:
- The migration issue is a recurring page shape, not a one-off sample repair.
- The fix needs both markup and behavioral evidence after normal transforms.
- The rewrite should stay isolated from the general transform list.
- The pattern can produce a better default output without pretending the migration is fully complete.
Do not use the catalog for simple token swaps, attribute normalization, or prefix stripping. Those still belong in the normal transform pipeline.
- Create a new class under
src\BlazorWebFormsComponents.Cli\SemanticPatterns\. - Implement
ISemanticPatternwith a stableId, anOrder, a small matcher, and a bounded applicator. - Register it in both places:
src\BlazorWebFormsComponents.Cli\Program.cstests\BlazorWebFormsComponents.Cli.Tests\TestHelpers.cs
- Add focused tests:
- catalog/runtime tests when behavior depends on ordering or pipeline placement
- concrete pattern tests for the new page shape
- Update this document when the catalog gains a new first-class entry.
Every new pattern should have:
- at least one positive test showing the rewrite that should occur
- at least one negative or boundary test showing the matcher does not overreach
- coverage proving the pattern works in the default production/test registration order
Use SemanticPatternCatalogTests.cs for catalog mechanics and SemanticPatternConcreteTests.cs for pattern-specific behavior.
The semantic pattern catalog improves migrated page output. Compile-surface filtering is a separate step that keeps risky legacy support files out of the generated SSR build by quarantining them under migration-artifacts\compile-surface\.
Keep these concerns separate:
- semantic patterns improve runnable migrated pages
- compile-surface filtering prevents unsupported legacy infrastructure from poisoning the generated build