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
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.
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");
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.
There are two approaches, we can either force the validator to render attributes or change the ID value to remove unwanted characters.
The first is obviously the better one but as you will see is a global application change.
Instruct the validator to render attributes
The validator controls are ready to work in a legacy mode, but to enable that mode we need to change the all behavior of our application. We can do that adding the following web.config data:
<system.web> <xhtmlConformance mode="Legacy"/>
While this solution is the one I like the most I choose to use the other simply because I don’t know exactly the potential side-effects, and I need to made a chirurgical change minimizing impacts.
Change the controls ID
That is not my case. It took me some time to find where the pageBody-2 control.
I ended up finding that it 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.