Developers often ask me what they can do to improve web standards on their ASP.NET website. There are a number of tricks available and I thought I'd share them with you.
Web.Config magic
First thing to do, is to make sure you've got your Web.Config ready for web standards. This is really simple, as there's only some copy and paste needed. What you want to do is setting xhtmlConformance mode to Strict and make use of browserCaps, both in the system.web section, like this:
<system.web>
<xhtmlConformance mode="Strict" />
<browserCaps>
<case match="W3C_Validator*">
TagWriter = System.Web.UI.HtmlTextWriter
W3CDomVersion = 1.0
</case>
</browserCaps>
....
</system.web>
Use the best .NET controls at your disposal
Countless of times you see .NET controls such as Label and Panel used. Not good, since both render extra HTML output. A label renders an extra span and a Panel renders an extra div, thus affecting the markup of the website - and at worst even breaking the layout.
To the rescue, comes the Literal and PlaceHolder controls. The Literal and PlaceHolder don't render extra markup, and I've never ran into a single problem using them instead.
Also, I like to use the Repeater as often as I can, since I don't always trust third party controls.
Set CSS class on the first listing item
You might have seen class="first" set on the first item in a listing, a number of times. For some, this is a pain to address. However, nothing could be easier than setting a specific CSS class on the first item in a listing. You just have to use the onItemDataBound event on your control. Here's how it might look:
<asp:Repeater ID="rptListing" OnItemDataBound="cssAddons" runat="server">
<ItemTemplate>
<li<asp:Literal ID="cssClass" Visible="false" runat="server"> class="first"</asp:Literal>>
<%#Eval("Item") %>
</li>
</ItemTemplate>
</asp:Repeater>
And the codebehind:
protected void cssAddons(object sender, RepeaterItemEventArgs e)
{
ListItemType type = e.Item.ItemType;
if (type == ListItemType.Item)
{
if (e.Item.ItemIndex == 0)
{
Literal litCssClass = (Literal)e.Item.FindControl("cssClass");
if (litCssClass != null) litCssClass.Visible = true;
}
}
}
You should never be forced to rebuild a project when doing layout changes - that's why one would prefer to use a hidden Literal with the CSS class in the ItemTemplate, and toggling the visibility if it's the first item in a listing.
Customized web controls and CompositeControl
A lot of you are perhaps writing your own web controls. Take note though, inheriting from CompositeControl will make your web controls render an extra span. There's a simple solution to this - just override the Render method in your control, like this, and you're set:
protected override void Render(HtmlTextWriter writer)
{
RenderContents(writer);
}
Some reminders - naming conventions and id's
When it comes to ASP.NET and naming web controls, things can get messy. You want to name your controls as short as possible, without making the name totally meaningless. You particularly want to name your ContentPlaceHolders in a smart way, to avoid id's like this:
ctl00_ContentPlaceHolderContent_ContentPlaceHolderMain_ContentPlaceHolderWidePageWithoutTopImage_ContentPlaceHolderWidePage_ContentPlaceHolderPageContent_ButtonSend
I regularly prefix my web controls, rpt for Repeater, cph for ContentPlaceHolders and so on.
Another problem in ASP.NET Web Forms is id's. If you use runat="server" with a HTML element, the id might look like in the example above. You must avoid this as much as you can, since the altered id's might break the layout. Some might say you should use CSS classes instead, but that's not the way to go. CSS classes aren't meant to be used instead of id's.
In ASP.NET 4, you can actually choose how your id's are rendered, through the ClientIdMode property. A welcome change!
More reading
Remember this is aimed at ASP.NET Web Forms websites, even though part of the tricks can be used in an MVC environment too!