04/14/2008

Clean Up ASP.NETs Head Tag With ControlAdapters

Ok, if you’re anything like me you absolutely gag when you see the rendered content of the ASP.NET head tag. It is all rendered out inline for some reason. I’m not 100% sure about the affects of it on web marketing, but I know one thing is for sure… It certainly doesn’t help your rankings any. At the very least it looks gross and it can be easily fixed with some portable c# files that you can include in any project. I found a reference here about it, so I picked it up and ran with it.

A couple of good things to note is the placement of some key pieces for control adapters in the .NET framework. The ControlAdapter class should be inherited for every control adapter you create, it can be found in the System.Web.UI.Adapters namespace. All of the tags we will be overriding belong to the System.Web.UI.HtmlControls namespace.

The first tag we will override is the head tag itself.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System.Web.UI; 
using System.Web.UI.Adapters;
using System.Web.UI.HtmlControls;
namespace Rollem.ControlAdapters
{
public class HtmlHeadAdapter : ControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
HtmlHead headTag = (HtmlHead)this.Control;
writer.WriteBeginTag("head");
if (!string.IsNullOrEmpty(headTag.ID))
writer.WriteAttribute("id", headTag.ClientID);
writer.Write(HtmlTextWriter.TagRightChar);
foreach (Control item in headTag.Controls)
item.RenderControl(writer);
writer.WriteLine("");
}
}
}

Next we are on to the title tag.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
using System.Web.UI; 
using System.Web.UI.Adapters;
namespace Rollem.ControlAdapters
{
public class HtmlTitleAdapter : ControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
writer.WriteLine();
writer.WriteFullBeginTag("title");
writer.Write(Page.Title);
writer.WriteEndTag("title");
writer.WriteLine();
}
}
}

Now the link tags.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System.Collections; 
using System.Web.UI;
using System.Web.UI.Adapters;
using System.Web.UI.HtmlControls;
namespace Rollem.ControlAdapters
{
public class HtmlLinkAdapter : ControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
HtmlLink linkTag = (HtmlLink)this.Control;
writer.Write("<link");
AttributeCollection attributes = linkTag.Attributes;
IEnumerator keys = linkTag.Attributes.Keys.GetEnumerator();
while (keys.MoveNext())
{
string key = (string)keys.Current;
if (key.ToLower() == "href" && attributes[key].Contains("~"))
writer.WriteAttribute(key, linkTag.ResolveClientUrl(attributes[key]));
else
writer.WriteAttribute(key, attributes[key]);
writer.WriteLine(" />");
}
}
}
}

Last but not least, the meta tags.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System.Web.UI; 
using System.Web.UI.Adapters;
using System.Web.UI.HtmlControls;
namespace Rollem.ControlAdapters
{
public class HtmlMetaAdapter : ControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
HtmlMeta metaTag = (HtmlMeta)this.Control;
writer.WriteBeginTag("meta");
if (!string.IsNullOrEmpty(metaTag.HttpEquiv))
writer.WriteAttribute("http-equiv", metaTag.HttpEquiv);
if (!string.IsNullOrEmpty(metaTag.Name))
writer.WriteAttribute("name", metaTag.Name);
writer.WriteAttribute("content", metaTag.Content);
writer.WriteLine(HtmlTextWriter.SelfClosingTagEnd);
}
}
}

Now all we have to do is setup a *.browser file in the App_Browsers folder to map the control adapter overrides.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<browsers>     
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlHead"
adapterType="Rollem.ControlAdapters.HtmlHeadAdapter" />
<adapter controlType="System.Web.UI.HtmlControls.HtmlTitle"
adapterType="Rollem.ControlAdapters.HtmlTitleAdapter" />
<adapter controlType="System.Web.UI.HtmlControls.HtmlMeta"
adapterType="Rollem.ControlAdapters.HtmlMetaAdapter" />
<adapter controlType="System.Web.UI.HtmlControls.HtmlLink"
adapterType="Rollem.ControlAdapters.HtmlLinkAdapter" />
</controlAdapters>
</browser>
</browsers>

Now if we right click and view source we will see a nice clean head tag.

Don’t live a moment longer with that ugly ASP.NET rendered head tag! 

Hope this helps!


comment: