Skip to content

CLI: Parse namespace-level tag prefix registrations from Web.config #550

@csharpfritz

Description

@csharpfritz

Context

DepartmentPortal's Web.config registers tag prefixes at the namespace level, not via src= file paths:

<pages>
  <controls>
    <add tagPrefix="uc" namespace="DepartmentPortal.Controls" assembly="DepartmentPortal" />
    <add tagPrefix="local" namespace="DepartmentPortal.Controls" assembly="DepartmentPortal" />
    <add tagPrefix="uc" src="~/Controls/QuickStats.ascx" tagName="QuickStats" />
  </controls>
</pages>

The first two entries use namespace= + assembly= to resolve any type in the DepartmentPortal.Controls namespace as a tag under the given prefix. This means <local:SectionPanel>, <local:EmployeeDataGrid>, <uc:EmployeeCard>, etc. all resolve to code-only C# server control classes — there is no .ascx file involved.

The CLI currently only handles src=-based control registrations (the third entry above, which points to an .ascx file). Namespace-level registrations are silently ignored, leaving all local:TypeName and uc:TypeName references in page markup unresolved during migration.

Impact

Every page in DepartmentPortal that uses a local: or uc: prefixed code-only control will have those tags pass through the pipeline untransformed — resulting in invalid Blazor markup that references non-existent components.

Affected pages include: Announcements.aspx, Resources.aspx, Employees.aspx, EmployeeDetail.aspx, Training.aspx, Admin/ManageEmployees.aspx.

Proposed Fix

Part 1 — Extend WebConfigTransformer

Parse <add tagPrefix namespace=... assembly=...> entries and build a prefix → namespace map in the migration context. This map should be passed into the markup transform pipeline alongside the existing src=-based control map.

Part 2 — New LocalTagNamespaceResolutionTransform (markup transform)

Create a new IMarkupTransform that:

  1. Receives the prefix → namespace map from Part 1
  2. Scans markup for <prefix:TypeName ...> elements where prefix is a registered namespace prefix
  3. Resolves the type by looking up TypeName in the discovered code-only control stubs (emitted by CodeOnlyControlScaffolder)
  4. Rewrites <local:SectionPanel ...><SectionPanel ...> (or the correct Blazor component reference)
  5. Handles both self-closing and block-level forms

Web.config Pattern Being Addressed

<!-- Namespace-level (NEW — not currently handled) -->
<add tagPrefix="local" namespace="DepartmentPortal.Controls" assembly="DepartmentPortal" />

<!-- Src-level (existing — already handled) -->
<add tagPrefix="uc" src="~/Controls/QuickStats.ascx" tagName="QuickStats" />

Registration

Per project conventions, the new transform must be registered in both:

  • src/BlazorWebFormsComponents.Cli/Program.cs (DI registration)
  • tests/BlazorWebFormsComponents.Cli.Tests/TestHelpers.cs (CreateDefaultPipeline())

Acceptance Criteria

  • WebConfigTransformer parses <add tagPrefix namespace=... assembly=...> entries and builds a prefix→namespace map
  • LocalTagNamespaceResolutionTransform is implemented and registered in both Program.cs and TestHelpers.cs
  • <local:SectionPanel>, <local:EmployeeDataGrid>, <uc:EmployeeCard> etc. are correctly rewritten to Blazor component references
  • Self-closing and block-level element forms are both handled
  • Transform integrates with CodeOnlyControlScaffolder output (see companion issue)
  • Tests added to tests/BlazorWebFormsComponents.Cli.Tests/

Notes

This is Tier 1 Critical Blocker P2 from the DepartmentPortal gap analysis. Without this, every local: prefixed markup tag on 6 DepartmentPortal pages passes through untransformed, producing invalid Blazor markup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmigration-toolkitCLI migration pipeline and toolkit enhancements

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions