ASP.NET has been taking a lot of hard words since the beginning. Many of the complaints are well deserved, but there are some ways to make things slightly better.


Unfortunately, this version is pretty much beyond any salvation and I hope most people have left it by now. It was released in 2000, which means that the technology was conceived during the late nineties and being quite outdated today.

The Web Controls mostly generate invalid XHTML, but there are several ways to handle this (more on this later). It’s also very important to stay away from the design mode, since it could quickly alter your markup without asking.

Also, turn off adaptive rendering to avoid generating different code for different browsers (which is always a bad idea) and reduce ViewState if you don’t need it.


An improvement is that the design mode does not change the markup by itself any longer, but you should stay away from the design mode.

The web controls mostly validate, but they are still a mess. Custom Web Controls automatically render <span> elements around the controls, which lead to invalid constructions such as block elements placed inside inline elements.

Some controls generate obtrusive JavaScript and a lot of the .NET stuff use the generated “javascript:__doPostBack” event. In plain English, using these controls will make checkpoint 6.3 of WCAG 1.0 fail. Not great, since this item has conformance level A.

The infamous table grids are all over the place. Controls such as MenuView, TreeView and DetailsView generate layout tables by default, which is breaking checkpoint 5.3 of WCAG 1.0 (conformance level AA).

If you wonder why empty alt-attributes are not rendered, you have to activate GenerateEmptyAlternateText. You could also run into trouble when the names of your control are mangled and prefixed with things such as “ctl00_MainContent_”.

There are solutions to all this. You could for instance write your own controls, or use HTML Controls instead of Web Controls, or write code to intercept the markup just before it is sent to the web browser and make corrections on the fly. If you don’t like the idea of writing your own controls from scratch, have a look at the CSS Adapters (more details below).

XHTML conformancy

ASP.NET 2.0 emits XHTML 1.0 Transitional content by default. You cannot choose a Strict DOCTYPE from the IDE, but you can configure how your ASP.NET site render the markup by using the xhtmlConformance element in web.config:

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

The mode attribute can be Legacy, Transitional or Strict. Please note that it must be called “Strict” and not “strict”. If you follow MSDN which says “strict”, you will get a runtime ConfigurationErrorsException.

Migrating 1.1 sites to 2.0 could enable Legacy mode, which will kill partial page updates when using ASP.NET AJAX UpdatePanel controls.


In addition to using compliance filters, you can create a folder called “App_Browsers”. This folder may contain browser definitions that ASP.NET uses to identify browsers and determine their capabilities, replacing the old browserCaps element. The .browser files uses the Browser Definition File Schema.

ASP.NET does not recognize the W3C Validator and thus serves it legacy code which makes the page fail validation. One way of dealing with this is to put a w3cvalidator.browser file in App_Browsers.

Which leads on to…

CSS Adapters

The CSS Friendly Control Adapters transform the ASP.NET output to a CSS-related output. They participate in the rendering phase and don’t intercept the markup output, to make them as fast as possible. They also use .browser files mentioned above.

As always, be careful since it involves JavaScript postbacks. I’ve read about issues concerning double postbacks for certain controls when using adapters. The second postback causes the controls to throw errors since the control changed the state in response to the first postback.

This should be the default setting for web controls in the IDE environment. Very few .NET developers will code their own adapters just to control the markup.

CSS adapters are certainly not perfect, but at least an alternative to the vanilla controls. For more details on CSS adapters, have a look at my article Creating CSS Control Adapters.


  • avatar
    08 Oct, 2007

    Great stuff that will come in handy when I sink my teeth into ASP.NET! :)

  • avatar
    08 Oct, 2007

    Thanks! There’s a lot to sink your teeth into, so get started right away. Just be careful with selecting your reading material, since a lot of articles on the net are written for version 1.1.

  • avatar
    Zach Baker
    03 Feb, 2009

    Also, turn off adaptive rendering to avoid generating different code for different browsers (which is always a bad idea) and reduce ViewState if you don’t need it.
    I’m sorry, but that is just plain wrong. There are many reasons you would want browser-specific rendering. Some of your more advanced things have to be rendered browser specific to work in ie6. And more than this, mobile devices are quickly becoming mainstream. Because they all take their own perspective on XHTML conformance, you have to sometimes do things uniquely for browsers, and it is a LOT easier to let .NET handle those things for you then to write your code explicitly in a browser-specific way.

  • avatar
    06 Feb, 2009

    Zach, thanks for your input!
    My advice for turning off adaptive rendering was primarily directed towards ASP.NET 1.1. As far as I know, those controls render HTML 3.2-compliant HTML by default which can break the rendering in non-IE6 browsers. This can be fixed by updating the browserCaps section in machine.config, where different browsers are labelled as uplevel or downlevel. By default only IE was labelled as uplevel.
    In ASP.NET 2.0 the browserCaps element has been deprecated and replaced by browser definition files. These are used by the CSS control adapter technique mentioned, and could be useful if you want customized rendering for mobile devices.

Leave a reply