It is not a secret that I have a passion related to ASP.NET Controls ID and all related subjects.
This time I’ll write about a problem I found while migrating a NetFx 1.1 application to a new server.
The problem is about Validators and how they render the data needed to validate Client-Side.
Scenario NetFX 1.1.4
All data is rendered thru attributes and this way they must only follow the attributes naming conventions.
Scenario NetFX 2.0 or higher
Most required data is rendered thru Expando attributes. This means that an javascript object is created to host the required data.
At first look this seems quite the same, only with a different storage approach, but it hides one tricky issue related to naming convention differences between Html attributes and Javascript variables.
The tricky issue
I believe that most of us tries to follow the best patterns and naming conventions and if we all did this on old applications this wouldn’t be a problem.
While migrating an old .Text v0.91 application to a new server, without NetFX 1.1 installed, I found that all pages with Validators raise a javascript error.
Digging into it I found the error in this line:
var ctl00_pageBody-2_RequiredFieldValidator1 = document.all ? document.all["ctl00_pageBody-2_RequiredFieldValidator1"] : document.getElementById("ctl00_pageBody-2_RequiredFieldValidator1");
The problem is obvious, the character ‘-‘ is a javascript operator and cannot be used in a variable name . The javascript parser after finding the ‘-‘ say that an ‘;’ is expected after ‘ctl00_pageBody’.
So … Why this didn’t occurred in the old server? What lead us to this point?
As I noticed before, in NetFX 1.1 this object didn’t exist, all data were simple rendered as attributes.
I didn’t find any good reason for naming a control like this but in fact this is a absolutely valid control ID.
The hard to find answer was “Where is the pageBody-2 control?”.
I ended up finding that this was an UserControl, loaded dynamically and its ID was also composed dynamically. Unfortunately, this was all done in a private method belonging to an internal base class and the only practical solution was to override the Page Render method and replace the pattern ‘_pageBody-‘ with ‘_pageBody_’.
I know it is a dirty solution … I don’t like it … but this is a short term solution before migrating the application to CommunityServer.
Mental note
Never use the ‘-‘ to name your controls ID property. Try the ‘_’ or any other without special meaning in Javascript.