Better Markup with Control Adapters

Ian Muir
Ian Muir

Of all the prominent server-side languages, ASP.NET definitely has the worst reputation amongst designers. Many of the controls in ASP.NET rely on table structures, inline styles and various other things that make a web designer’s life difficult. In an effort to alleviate this in ASP.NET 2.0, Microsoft introduced a new theme system. Unfortunately, the only thing you could really do with these themes was change the class names assigned to the table structures.

Fortunately, ASP.NET does have a great feature called control adapters that allows developers to have more control over the markup generated by the controls. In fact, a few months ago Microsoft released an entire set of pre-built CSS friendly control adapters. These pre-built adapters are a great way to cleanup the markup of many of the ASP.NET server controls, but they may not be exactly what you’re looking for. This post will shed some light on the process of building your own control adapters.

Before proceeding too far into this process, you should download and test the CSS friendly adapter set; they provide a good reference while building your own adapters.

The main purpose of using control adapters is to alter how the built-in controls are rendered. Using these adapters requires 2 things: an adapter class and a browser definition file. The adapter class defines how the control will be rendered and the browser definition file determines which browsers or agents should use the adapters.

The adapter class is used to override the rendering functions of the original control. The class must inherit the appropriate adapter from the WebControls.Adapaters namespace (for example an adapter for menu controls would inherit WebControls.Adapters.MenuAdapter). The base adapter class contains the rendering functions that you will be overriding in your control adapter. You should also create a property that contains an instance of the WebControlAdapterExtender class. The extender class will save you from writing a lot of code and will help you make sure that your adapted controls still function correctly.

The main functions you will be working with are RenderBeginTag, RenderEndTag, and RenderContents. If you control will need access to any javascript, you can also use the RegisterScripts function to add them to the header.

The RenderBeginTag and RenderEndTag can be generated using the extender. The extender will create a div with an ID that your code-behinds and other controls can recognize. The RenderContents function is where you will actually be generating your markup. You can access any properties of the server control being rendered through the Control property and use the writer parameter to output the markup. The MenuAdapter class in the CSS friendly adapters is a good example of how to render the contents of a control. It reads through the Items property of the menu and uses a pair of functions to render either an unordered list or list item.

The RegisterScripts function is used to attach any javascript files you might need. The benefit of using RegisterScripts is that it will place the script tag for your javascript file in the page’s header not in the body. It will also prevent the same file from being referenced multiple times. If for some reason you need to have the javascript placed in the body, which is usually bad, you can render it in the RenderContents function.

Hopefully this post sheds a bit more light on how to use control adapters for your ASP.NET applications. These adapters will definitely help you make a more standards compliant site and will help keep your designers happy.