Wednesday, 20 February 2008

Control name changes due to xhtmlConformance

Another strange and unwanted ASP.Net problem cropped up today when we least needed it to. We had some code problems occurring on some servers, but the exact same code worked fine on other servers. The problem was related to some code that hadn't changed for a long time, and left the development team scratching our heads.

Turns out in the HTML the naming convention for controls were different for controls rendered between the different sets of servers. The HTML control name attributes that were separated by a colon : were now being separated by a dollar sign $ in the name property, the id attribute however stayed constant.

This would cause problems in certain scenarios for Javascript and Serverside parsing of the html form values; basically anywhere the element name was hard coded using the : seperator would now not find the control.

The problem relates back to our transition from .Net 1.1 to .Net 2 (so I'm surprised this took so long to surface) and a similar problem that cropped up with some AJAX integration a while back to do with an xhtmlConformance setting.

ASP.Net 1 and 1.1 did not emit XHTML compliant markup from countless server controls. ASP.Net 2 changed this and defaults to emitting XHTML compliant markup from all controls. Beta testing of ASP.Net 2 showed Microsoft that this could affect certain web apps and to prevent this a xhtmlConformance setting was introduced and added in the conversion to the framework's web.config file:

<system.web>
   <xhtmlConformance mode="Legacy" />
</system.web>

Basically, with the setting set to legacy the following example html control output would be rendered:

<input type="text" name="ParentControl:Control" id="ParentControl_Control" />

With the setting set to Transitional (Default) or Strict the following example html control output would be rendered:

<input type="text" name="ParentControl$Control" id="ParentControl_Control" />

I would recommend you don't set the setting to Legacy and leave it as the default Transitional or set to Strict as this will result in your HTML from your server controls to be well formed (i.e. all tags are closed for all elements). Important in ASP.Net AJAX implementations as mentioned in this post.