CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Brendan Tompkins [MVP]

Blog First. Ask Questions Later.

Dynamically Adding <HEAD> Content with ASP.NET

I recently came across a situation where I needed to dynamically add HTML content to the <HEAD> section of every page on our site.  I needed this, for a couple of reasons. 1) I wanted to allow users to dynamically specify different style sheets to apply to the entire site.  2) I had to import some .HTC references whenever a control on a page needed to use a sticky draggable div control.

The first thing I tried was to simply give my <head> tag an id and the runat=server attribute.  This way, I could include a method to my site PageBase class that pops content into the <head> tag.  By the way, PageBase is simply a class that inherits from System.Web.UI.Page, from which I base all of my aspx classes.  If you're not already sub-classing a page base for your app, you may want to look into this.  Anyhow, this worked, but had one MAJOR drawback...  The Visual Studio IDE would remove the runat=server attribute from my <head> tag, whenever the view was switched to HTML or when the page was saved.. Well, I couldn't deal with having to remember to add it back every time I saved, so I went looking for a new approach. 

The approach I came up with involves adding a couple of methods to my PageBase Class to register any content I want to have appear in my HEAD section:

private Hashtable m_registeredHeadContent;

public void RegisterHeadContent(string key, string content)
{
   
if(this.m_registeredHeadContent == null) {
       
this.m_registeredHeadContent = new System.Collections.Hashtable();
    }

   
if(!m_registeredHeadContent.ContainsKey(key)){
       
this.m_registeredHeadContent.Add(key, content);
    }
}

public string RegisteredHeadContent
{
    
get
    
{
        
string strReturn = null;
        
if(m_registeredHeadContent != null)
        {
            
foreach(string s in m_registeredHeadContent.Values) strReturn += s;
        }
        
return strReturn;
    }
}

So, now whenever I want to add something, like an HTC import, I just add a call to the “RegisterHeadContent” method from my ascx controls or WebControl.  Now how to get this content into the HEAD section of my page.  You really have two options, add a classic style server tag, like so to your <HEAD> section:

<%=RegisteredHeadContent%>

or you could create a control deriving from System.Web.UI.HtmlControls.HtmlGeneric control, drop on your form in your <HEAD> section.  This control needs to retrieve the RegisteredHeadContent from your PageBase class.  I created one, which my friend Brandon Boyd aptly named for me “HtmlHeadContentInjector“ ;)

public class HtmlHeadContentInjector : System.Web.UI.HtmlControls.HtmlGenericControl
{
    // Needs this constructor
    public HtmlHeadContentInjector(string tagname){}

    protected override void Render(HtmlTextWriter writer)
    {
        string headContent = ((PageBase)this.Page).RegisteredHeadContent;
        writer.Write(headContent);
    }

    // Override, don't render atts
    protected override void RenderAttributes(HtmlTextWriter writer){}

    // Override, don't render end
    protected override void RenderEndTag(HtmlTextWriter writer){}
}

Which option you choose is up to you.  Personally, I don't like poking too many holes in my ASPX pages using the <%=%> syntax, but don't have any hard evidence against this method..

-Brendan



Comments

Brendan Tompkins said:

Hi.. Check your source, you probably are writing "ACME Company" somewhere. They key is just the hash key. Try


RegisterHeadContent("title", "<title>ACME Company</title>");
# September 23, 2004 1:43 AM

zmrcic said:

I have a user control and I will like to put style tag in page's header section...
Haw can I do that...
Thaks...
# October 24, 2004 11:29 PM

Jørn Cornelius Olsen said:

It works. However the id attribute is not allowed on the head element. Could it be removed in the rendering somehow?
# August 4, 2005 6:22 AM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add

About Brendan Tompkins

Brendan has been programming with .NET since the first public beta and is owner and operator of Port Technology Services, a consultancy company providing .NET application development services to the Maritime industry. In July, 2007, he was awarded the Microsoft MVP award for ASP.NET. He's also a proud co-founder of failed .COM startup Intrinsigo, and has had a hand in the failure of numerous other businesses. He currently runs CodeBetter.Com and Devlicio.us, and lives in Norfolk, Virgina with his wife Tiara and son Ian.

View Brendan's profile on LinkedIn

Check out Devlicio.us!

Our Sponsors

Free Tech Publications