Skip to content

CLI: Add code-only server control scaffolder for DepartmentPortal-style controls #549

@csharpfritz

Description

@csharpfritz

Context

DepartmentPortal has 7 code-only server controls (no .ascx file) in samples/DepartmentPortal/Code/Controls/*.cs. These controls inherit from CompositeControl, DataBoundControl, Control, WebControl, and IPostBackEventHandler — they are pure C# server controls with no markup file.

The CLI pipeline currently only discovers .ascx user controls. Code-only controls in Code/Controls/ are entirely invisible to the migration pipeline. They are referenced in page markup via local:ControlName tag prefix (registered as a namespace-level tag prefix in Web.config) but no scaffolding is emitted for them.

Jeff's directive: "these should migrate directly with our shim control classes — we need a migration class in the CLI"

The 7 Code-Only Controls Found

Control Base Class(es) Used On
SectionPanel Control, INamingContainer, [ParseChildren(true)], ITemplate props Announcements.aspx (×1), Resources.aspx (×3)
EmployeeDataGrid DataBoundControl (overrides PerformDataBinding + RenderContents) Employees.aspx, Admin/ManageEmployees.aspx
EmployeeCard CompositeControl (overrides CreateChildControls) EmployeeDetail.aspx
PollQuestion Control, IPostBackEventHandler (implements RaisePostBackEvent); uses Page.ClientScript.GetPostBackEventReference Training.aspx
StarRating WebControl (overrides RenderContents, TagKey) EmployeeDetail.aspx
NotificationBell WebControl; raises NotificationClicked / NotificationDismissed events Defined only (not yet placed on a page)
DepartmentBreadcrumb Control, IPostBackEventHandler; uses Page.ClientScript.GetPostBackEventReference Defined only (not yet placed on a page)

Source Location

samples/DepartmentPortal/Code/Controls/

Proposed Approach

Create a CodeOnlyControlScaffolder class in src/BlazorWebFormsComponents.Cli/Scaffolding/ that:

  1. Scans C# files under the source project for classes that inherit from WebControl, CompositeControl, DataBoundControl, or Control
  2. Skips known System.Web framework types (only emits stubs for user-defined controls)
  3. Emits a Blazor .razor + .razor.cs component stub pair for each discovered control
  4. Maps Web Forms base classes to BWFC shim base classes:
Web Forms Base BWFC Base Class
WebControl BaseStyledComponent
CompositeControl BaseWebFormsComponent
DataBoundControl DataBoundComponent<T>
Control BaseWebFormsComponent
  1. Preserves public properties from the original class as [Parameter] properties in the emitted .razor.cs
  2. Preserves public events from the original class as EventCallback or EventCallback<T> parameters

The scaffolder should run as part of the MigrationPipeline before markup transforms so that discovered controls are available when LocalTagNamespaceResolutionTransform (see companion issue) resolves local: tags.

Acceptance Criteria

  • CLI discovers all 7 code-only controls in DepartmentPortal's Code/Controls/ folder
  • A .razor + .razor.cs stub pair is emitted for each discovered control
  • Each emitted stub compiles against its BWFC base class without errors
  • Public properties from the original class are preserved as [Parameter] in the stub
  • Public events from the original class are preserved as EventCallback or EventCallback<T> parameters
  • Scaffolder is registered in MigrationPipeline and integrates with the LocalTagNamespaceResolutionTransform
  • Tests added to tests/BlazorWebFormsComponents.Cli.Tests/

Notes

This is Tier 1 Critical Blocker P1 from the DepartmentPortal gap analysis. Without this, 7 controls used across multiple DepartmentPortal pages produce no output, and all local: markup references fail to resolve.

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