user746461
user746461

Reputation:

How are HTML tags converted to HtmlControl?

Suppose I have this markup:

<asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
        <a runat="server" id="myLink" href="<%# Container.DataItem %>">Here</a>
    </ItemTemplate>
</asp:Repeater>

In the code-behind, I can find out that <a> is converted to HtmlAnchor:

private void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    HtmlAnchor myLink = (HtmlAnchor)Repeater1.FindControl("myLink");
}

But how does the compiler know that <a> is HtmlAnchor? Is it hard-coded in the compiler?

If I write

<asp:Repeater ID="Repeater1" runat="server">
    <ItemTemplate>
        <Foo href="<%# Container.DataItem %>">Here</a>
    </ItemTemplate>
</asp:Repeater>

and want the <Foo> tag to be converted to my HtmlFoo class, how do I achieve that?

I just want to have a deeper understanding of the compilation process behind the scenes.

Upvotes: 3

Views: 572

Answers (2)

Michael Liu
Michael Liu

Reputation: 55359

You can learn a lot about the internals of ASP.NET by delving into the Reference Source.

It turns out that the mapping from unprefixed HTML tags to HtmlControl subclasses is hard-coded in an internal class called HtmlTagNameToTypeMapper:

static Hashtable _tagMap;

Type ITagNameToTypeMapper.GetControlType(string tagName, IDictionary attributeBag) {
    Type controlType;

    if (_tagMap == null) {
        Hashtable t = new Hashtable(10, StringComparer.OrdinalIgnoreCase);
        t.Add("a", typeof(HtmlAnchor));
        t.Add("button", typeof(HtmlButton));
        t.Add("form", typeof(HtmlForm));
        // [and much more...]
        _tagMap = t;
    }

    // [...]
}

GetControlType is called by another internal class called MainTagNameToTypeMapper:

int colonIndex = tagName.IndexOf(':');
if (colonIndex >= 0) {
    // [...]
}
else {
    // There is no prefix.
    // Try the Html mapper if allowed
    if (fAllowHtmlTags) {
        return _htmlMapper.GetControlType(tagName, attribs);
    }
}

There's no public API to register more unprefixed HTML control types.

On a more localized scale, it is possible for a parent control to customize how the tag names of its child controls are interpreted. To do this, derive from ControlBuilder, override GetChildControlType, and decorate the parent control class with the [ControlBuilder(typeof(...)] attribute.

Upvotes: 1

TheRotag
TheRotag

Reputation: 418

When you add runat="server" to a control in ASP.NET, a corresponding variable of type HtmlControl (or some subclass thereof) is automatically added to your page (in the designer file). That way you can access that control as a variable. For most common HTML controls, there are subclasses of HtmlControl (such as HtmlAnchor for anchor/link tags). Other controls (such as <div>) get the HtmlGenericControl type. For those, you specify the tag (div) as a property. So your Foo tag would get like a div: a variable of type HtmlGenericControl with a tag of "Foo".

Edit: this is for standard HTML elements. If you create an ASP control (such as <asp:TextBox...>, then the resulting variable will be a subclass or WebControl instead of HtmlControl.

Upvotes: 0

Related Questions