My fantastic Webdings Logo

Reamped.NET

It's not that bad


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.

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.

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.

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.

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.

<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.

Before:

After:

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

Download the code:
HtmlHeadControlAdapters.zip (12.70 kb)

Updated to have the code copyable & using the ResolveClientUrl function 

 

kick it on DotNetKicks.com


Related posts

Comments

Dave Transom

It looks to me like it's only tidying up the whitespace within the head (adding line breaks).

This won't effect your search engine rankings at all. I grant you that it does look much better though - so I like it Smile Plus, it's a nice simple example of using control adapters.

PS: You replace the tilde(~) character in ALL attributes of the HtmlLink. I think what you wanted to do was do a ResolveUrl() call instead, and for the href attribute only? There are url's that have the ~ character.



Ira

Good call!

I totally agree with the ResolveUrl call, that would be the correct way of doing it. As far as the rankings thing goes, there is no proof to either sides of the story. All I know is that if it is this easy to have it render more eye-ball friendly, then I should take the time to do it.



Seth Petry-Johnson

As far as the rankings thing goes, there is no proof to either sides of the story.

Why would you think this WOULD have an impact on rankings? The search engine spider doesn't care how much whitespace is between the various META tags and such, just that the HEAD section is valid markup. Line breaks (or the lack thereof) don't have any bearing on HTML validation and therefore should have no impact on rankings. (Not to mention that META tags are becoming less and less significant to modern engines like Google, but that's another discussion)

You should promote this technique only as a way to make the markup "prettier", not as something that will influence search rankings.



Seth Petry-Johnson

I do think this is a good introduction to the usage of control adapters. My apologies if my last comment came off a bit rough Smile



Ira

I do think this is a good introduction to the usage of control adapters. My apologies if my last comment came off a bit rough Smile

I thank you and appreciate the feedback. It doesn't sound rough, it sounds like you have some marketing know how. I know that it shouldn't matter the formatting or whitespace in the head tag. However, crappy formatting doesn't help you any. It would be safe to say that it also doesn't hurt! Smile

I also agree with the meta tags significance to the search engine. My motto today for web marketing is "Content is king!".



VIjay Santhanam

I've never used ControlAdapters before, but I'm told they're the new way to do mobile.asp.net dev (cos the MobileControls are unmaintained).
Thanks for a good introduction.




Cyril Gupta

Good introduction to control adaptors.

Thanks



Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]