Creating CSS Control Adapters

ASP.NET comes with a generous collection of pre-built controls designed to make web development faster and easier. And they do. Unfortunately, some of them also produce markup with all the grace and subtlety of a drunken rhinoceros rearranging your living room.

Accessibility? Web standards? Clean, semantic markup? Apparently these were occasionally treated as optional extras.

Take the GridView control, arguably one of the most popular additions to ASP.NET 2.0 and the shiny replacement for the old DataGrid. On the server side, everything looks perfectly civilized. Then you inspect what actually gets sent to the browser. That’s when things get interesting.

GridView renders itself as a <table> and insists on inserting a border attribute, regardless of how you configure the control’s border properties. You can plead with it. You can set properties. You can stare accusingly at Visual Studio. The attribute remains, squatting there in your markup like an unwanted houseguest. As far as I know, there’s no straightforward way in vanilla Visual Studio to stop it.

Sure, you could write an XSLT response filter and clean up the output afterward. You could also perform dental surgery with a Leatherman. Technically possible, perhaps, but there ought to be a better way. Fortunately, there is: CSS Control Adapters.

Despite the name, CSS Adapters aren’t really about sprinkling more CSS over the problem. They give you control over the actual markup generated by ASP.NET server controls. Instead of blindly accepting whatever HTML Microsoft has decided is good for you, you can tell a GridView to render as a <table>, <ul>, <div>, or something else entirely.

Control the markup and you control the presentation. More importantly, you have a fighting chance of producing HTML that doesn’t make a standards-conscious developer quietly reach for the strong stuff.

Technically, CSS Adapters plug into ASP.NET server controls and override their normal rendering logic. The nice part is that you don’t have to tear apart your application or rewrite the code-behind. Your existing control syntax remains the same, only the resulting markup changes.

To create one, you start with a class derived from the abstract System.Web.UI.Adapters.ControlAdapter class, which provides the basic machinery for control adapters. Inside your new class, you override the appropriate methods and generate the markup you actually want. The adapter then needs to be registered in a .browser file inside the App_Browsers directory. For example:

<browser refID="MozillaFirefox"> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.GridView" adapterType="Minkmachine.GridViewAdapter" /> </controlAdapters> </browser>

The .browser file also lets you decide which browsers receive which adapters. You can target specific browsers or even specific versions, allowing different rendering depending on who is asking.

If you want your adapter enabled for all browsers, use: refID=”Default”. Otherwise you may find yourself carefully fixing your markup for Firefox while everyone else continues receiving the original ASP.NET soup.

CSS Control Adapters aren’t a perfect solution. They add another layer to an already layered framework, and plenty of developers probably couldn’t care less what the final HTML looks like as long as the page appears roughly correct in Internet Explorer. But if you care about accessibility, web standards, semantics, or simply being able to look at your generated source without feeling vaguely ashamed, they provide something valuable: control over the markup. And in ASP.NET, sometimes getting the framework to stop helping you is half the battle.

Comments

No comments yet.

Leave a reply