Custom WebControl Migration
This page demonstrates how Web Forms custom controls that use WebControl base class
with RenderContents(HtmlTextWriter) work unchanged in Blazor through BWFC.
Demo 1: StatusBadge (TagKey + RenderContents + AddAttributesToRender)
A custom control that renders a badge with a data attribute and styled inner content.
Live Output:
Online
Warning
Offline
Component Code (unchanged from Web Forms):
public class StatusBadge : WebControl
{
public string Status { get; set; }
public string Label { get; set; }
protected override HtmlTextWriterTag TagKey
=> HtmlTextWriterTag.Span;
protected override void AddAttributesToRender(
HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
writer.AddAttribute("data-status",
Status?.ToLowerInvariant() ?? "unknown");
}
protected override void RenderContents(
HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Strong);
writer.Write(Label ?? Status);
writer.RenderEndTag();
}
}Demo 2: InfoCard (Complex Nested RenderContents)
A custom control that renders a card with a header and body using nested HTML elements.
Live Output:
Migration Complete
Your custom WebControl works in Blazor without code changes!
Custom Header Style
The HeaderCssClass parameter controls the header styling.
Component Code (unchanged from Web Forms):
public class InfoCard : WebControl
{
public string Title { get; set; }
public string Body { get; set; }
public string HeaderCssClass { get; set; }
= "card-header";
protected override HtmlTextWriterTag TagKey
=> HtmlTextWriterTag.Div;
protected override void RenderContents(
HtmlTextWriter writer)
{
// Header
writer.AddAttribute(
HtmlTextWriterAttribute.Class,
HeaderCssClass);
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.RenderBeginTag(HtmlTextWriterTag.H3);
writer.Write(Title);
writer.RenderEndTag(); // h3
writer.RenderEndTag(); // header div
// Body
writer.AddAttribute(
HtmlTextWriterAttribute.Class,
"card-body");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.Write(Body);
writer.RenderEndTag(); // body div
}
}How It Works
In Web Forms, custom controls inherit System.Web.UI.WebControls.WebControl and override:
TagKey— the outer HTML elementAddAttributesToRender(HtmlTextWriter)— attributes on the outer tagRenderContents(HtmlTextWriter)— inner HTML content
In Blazor with BWFC, you change only the using statement:
// Before (Web Forms)
using System.Web.UI.WebControls;
// After (Blazor + BWFC)
using BlazorWebFormsComponents.CustomControls;
The BWFC WebControl class provides an HtmlTextWriter shim that captures
all rendering calls and emits the result as raw HTML in Blazor's render tree. Your
RenderContents code runs unchanged.