Stupid .NET Tricks #8
November 12, 2007 10:40 pm programmingASP.NET, in its grand paternal wisdom, replaces the “id” attribute on any server-side-enabled control with a dynamically generated (and thus guaranteed to be unique) value. So, when you write this:
<div id="foo"></div>
…what you actually get is something like this:
<div id="ctl00$page_content_replace$ctl00$foo"></div>
…thus dashing any hope you had of writing proper DOM-aware content (such as JavaScript and CSS).
Update: Oh yeah, and it changes the “name” attribute of input fields too, thus ensuring that your form parameters and query strings are utterly nasty.
Update 2: JonEHolland writes (below):
Use the ClientID attribute to specify ID once the control is rendered.
IE:
<div ClientId=”someId” id=”ServerSideId” runat=”server”></div>
Renders:
<div id=”someId” ></div>
I tried setting ClientId (and ClientID and clientid) and it didn’t help for several reasons:
- ASP.NET did not actually copy my server-side ClientID attribute to the client-side ID attribute as JonEHolland stated. The id attribute was the same generated string.
- It did, however, pass the same ClientID attribute and value on to the client (basically it left the unrecognized attribute alone, as it should). That could be somewhat useful, especially if you’re generating arbitrary XML. However, it doesn’t solve the core problem of the munged IDs; CSS/JavaScript won’t recognize ClientID without a lot of extra hacking.
- ClientID isn’t valid in the XHTML 1.0 Strict DTD, so Visual Studio complains about it. If you use any uppercase letters (such as ClientID) it actually generates an error; if you stick to lowercase (clientid) it lets you off with a warning.
- On the C# side: the ClientID property of Control is read-only and thus not changeable to anything. (ID is changeable but the change is ignored/overwritten by the time the control is rendered — at least as far as I’ve probed. Perhaps there’s a point in the control lifecycle where you can actually set it? Even if there is it appears to be too dicey to be worthwhile.)
- The ClientID property does provide me with the ID that ASP.NET has chosen for the element. If I wanted to generate CSS or JavaScript that used the element’s ID, I could use this property to discover the ID that would be used. But that’s horribly ugly and restrictive.
Sorry, JonEHolland; it doesn’t look like this works. If I’ve missed something let me know, but it appears that you’re incorrect.
Update 3: JonEHolland points to this blog post by Rick Strahl which describes how to bypass the ID munging by overriding the UniqueID and ClientID properties. That’s better than nothing, and just fine if you’re developing your own controls, but it still doesn’t solve the problem for the standard ASP.NET controls (in System.Web.UI.WebControls and System.Web.UI.HtmlControls); you’d have to create a whole bunch of new classes.

November 10th, 2007 at 10:46 pm
Use the ClientID attribute to specify ID once the control is rendered.
IE:
<div ClientId=”someId” id=”ServerSideId” runat=”server”></div>
Renders:
<div id=”someId” >&;lt/div>
You really should rename this blog to “Another thing I don’t understand about .NET”
November 12th, 2007 at 10:21 pm
Sorry about that Craig. You are right.
ClientID simply returns the ID that will be generated by the framework for the client. I’m not sure what I was thinking with the original post…My apologies
The clientID generated is used by postback to help locate the control, so if you mess with it, you might have issues.
However, you can override it, as Rick has done here.
http://www.west-wind.com/WebLog/posts/4605.aspx