Reputation:
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
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
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