ASP.NET Custom Server Controls: Build, Register, Reuse

Last Updated: Nov 16, 2025
5 min read
Legacy Archive
Legacy Guidance: This article preserves historical web development content. For modern .NET 8+ best practices, visit our Tutorials section.

What a Custom Control Is

ASP.NET gives you many built‑in controls, but sometimes you need your own. A custom server control is compiled into a class that you can drop on many pages. It shows up in the Toolbox, supports properties and events, and ships as a single assembly.

Why pick a custom server control over a user control? A user control is great for quick UI reuse, but it lives in a single project and is harder to share. A custom control compiles into a DLL, so you can reuse it across sites, version it, and get design‑time support.

How It Works

You create a control by inheriting from a base class like WebControl or CompositeControl. Override lifecycle methods to render HTML, expose public properties for settings, and raise events so the hosting page can react.

Minimal control
using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace LegacySamples
{
    // Tiny label that renders a  with a prefix
    public class HelloLabel : WebControl
    {
        public string Text { get; set; } = "Hello";
        public string Prefix { get; set; } = "[info]";

        protected override void Render(HtmlTextWriter writer)
        {
            // Output: [info] Hello
            writer.RenderBeginTag(HtmlTextWriterTag.Span);
            writer.Write($"{Prefix} {Text}");
            writer.RenderEndTag();
        }
    }
}
Add at runtime
// Example: add the control in a page
using LegacySamples;

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var hello = new HelloLabel { Text = "Welcome", Prefix = "Site" };
        PlaceHolder1.Controls.Add(hello);
    }
}

Composite Controls

For richer behavior, use CompositeControl. It lets you compose child controls, wire up events, and expose a simple API to the page.

SearchBox control
using System;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace LegacySamples
{
    // Simple search box + button that raises a server event
    [ToolboxData("<{0}:SearchBox runat=\"server\" />")]
    public class SearchBox : CompositeControl
    {
        public event EventHandler Search;

        TextBox _query;
        Button _go;

        protected override void CreateChildControls()
        {
            _query = new TextBox { ID = "q" };
            _go = new Button { ID = "go", Text = "Search" };
            _go.Click += (s, e) => Search?.Invoke(this, EventArgs.Empty);

            Controls.Add(_query);
            Controls.Add(_go);
        }

        public string Query
        {
            get { EnsureChildControls(); return _query.Text; }
            set { EnsureChildControls(); _query.Text = value; }
        }
    }
}

Practical Tips

  • Expose simple properties and sensible defaults.
  • Validate input inside the control to avoid surprises.
  • Keep ViewState small. Use it only when the value must survive a postback.
  • Document the HTML output so CSS can style it cleanly.

Tips: keep rendering simple and predictable. Prefer properties with clear defaults. Use ViewState only when you need to persist values across postbacks. Document which HTML the control emits so teams can style it with CSS.

Build and Share

Distribution: build the control into a class library, sign it if needed, and reference the DLL from your Web Forms app. You can add it to the Toolbox and drag it onto pages. For global reuse, install it in the Bin folder or GAC.

FREQUENTY ASKED QUESTIONS (FAQ)

When should I choose a custom control rather than a user control?

Pick a custom control when you need a compiled, reusable control across many projects with Toolbox support. Use a user control for simple, page‑local reuse.

How do I handle events?

Expose .NET events on the control and raise them from child control handlers or lifecycle methods. The hosting page subscribes to those events.

Can I share a control across sites?

Yes. Build a class library DLL and reference it from each app. Put the DLL in the Bin folder or GAC if your policy allows.

Back to Articles