One common criticism of ASP.NET today is that the code it produces isn't valid XHTML but instead matches the HTML 4.01 Transitional doctype. XHTML is becoming increasingly prevalent on the web due to its compatibility with XML (it's just another XML schema) and ease of transformation to support other uses (e.g. for accessibility).

It's worth bearing in mind that when ASP.NET was first revealed at the PDC in 2000, the biggest concern on everybody's mind seemed to be compatibility with a wide range of browsers. Netscape Navigator 4.x and Internet Explorer 3.x / 4.x were all still relatively common, with varying levels of support for CSS and DHTML features. One of the big "wow" features of ASP.NET was that by flicking a setting on the Document object, you could change the way controls were laid out on screen from using absolute co-ordinates in CSS to using nested tables (for the broadest compatibility). Three years on from that initial PDC release, the vast majority of browsers adhere very closely to the W3C specifications, and compatiblity concerns have been replaced by concerns over conformance to new standards such as XHTML.

One piece of good news for those of you trying to retrofit ASP.NET to provide this functionality is that the Whidbey release of ASP.NET will generate XHTML 1.1-conformant pages. In a year or so's time, this will therefore be an academic discussion.

In the meanwhile, I've recently seen two separate developments which should hopefully reduce the pain of supporting XHTML within ASP.NET. Firstly, a colleague pointed me at the following article on the ASP.NET forums, which is from a company who are producing XHTML Strict 1.0 replacements of the standard server controls (thanks, Kieran!).

Secondly, I lately came across a clever trick for cleaning up the ViewState logic emitted by ASP.NET to be XHTML compliant. Well done to Charon for coming up with this trick. (Also see the posting on Scott Galloway's blog for another example).

Hopefuly these tips will save you some bother if you're trying to get ASP.NET to do what you want. Trying to look at all of this in a positive light, it's tribute to the extensibility and modularity of the ASP.NET architecture that it's possible to retrofit this kind of functionality into the engine - imagine trying to implement these kinds of changes in ASP!