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

Peter's Gekko

public Blog MyNotepad : Imho { }

Response.AppendHeader, Webforms and favicons

Perhaps I'm too naive on this but I'm stuck. Having turned the web upside down twice I'm still completely puzzled.

In the header of an aspx page's response is some meta-information to help the browser. One of the headers can be the stylesheet to use when rendering the page. Having linked a stylesheet in the webform designer (Format|Document styles in VS 2003) your page header will look something like this.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>Onderwijs</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
<LINK href="StyleSheetIndato.css" type="text/css" rel="stylesheet">
</HEAD>
<body>

Linking a stylesheet this way has two disadvantages

  1. You have to repeat it for every page in the application
  2. It is hard to maintain, switching style sheets requires editing all aspx files

Being an OOP guy I consider the best way to link the sheet is in my page base class. The Response object has an AppendHeader method, so this could be a nice way to set the stylesheet:

 protected override void OnPreRender(EventArgs e)
 {
   base.OnPreRender (e);
   Response.AppendHeader("LINK", string.Format("rel='stylesheet' type='text/css' href='{0}'></link>", System.Configuration.ConfigurationSettings.AppSettings["StyleSheet"]));
 }
 

The code tries to add a header to the response which contains the link to the stylesheet.

Alas this does not work. In all my tries the AppendHeader method does nothing at all when the response is rendered by a webform. And I've found no nice event to hook into or method to override. I had this frustration before, at the time the solution was to wrestle in the stylesheet link in the page body pretending it was a snippet of script.

protected override void OnLoad(EventArgs e)
{
    base.OnLoad (e);
    RegisterClientScriptBlock("MyStyleSheet", string.Format("<link rel='stylesheet' type='text/css' href='{0}'></link>", System.Configuration.ConfigurationSettings.AppSettings["StyleSheet"]));
}       
 

I'm still doing that, but recently revisited the subject and gave it another try. Another thing to put in a header is a shortcut icon, which is used in the browser's toolbar and favorites.

<HEAD>
  <LINK REL="SHORTCUT ICON" HREF="http://www.mydomain.com/myicon.ico">
  <TITLE>My Title</TITLE>
</HEAD>

This looks simple, but neither VS 2003 nor VS 2005 accepts even the markup. Let alone anything like Response.AppendHeader or injecting the link in the body will work.

As we say in Dutch it's giving me a pointed head. Any suggestion is more than welcome


Published Oct 31 2005, 11:38 AM by pvanooijen
Filed under:

Comments

Page Brooks said:

Maybe you could try something like this:
http://www.codeproject.com/useritems/HeadFilter.asp
# October 31, 2005 12:07 PM

daughtkom said:

Doesn't the Response.AppendHeader refer to HTTP headers as opposed to HTML headers?
# October 31, 2005 12:31 PM

breichelt said:

yep, daughtkom is right, you are appending an HTTP header to your response, which will just be ignored I'm guessing.

You're going to need to do a Response.Write(); or something like that to get your custom Html sent to the output stream. You could also make the "head" element a server control and then alter the .InnerHtml property of it, but this would cause you to modify every page again, which you are trying to avoid.

What I usually do is put all of my header information in a user control that I use in each of my pages, then when I want to edit something globally, I can add script files, css, etc. in the user control and its immediately included in each page.

-ben
# October 31, 2005 12:47 PM

Chris Slatt said:

I use <a href="http://authors.aspalliance.com/PaulWilson/Articles/?id=14">Paul Wilson's implementation of Master Page Templating</a> for .NET 1.1, then the style sheet, etc just get referenced once in the template file.
# October 31, 2005 1:22 PM

Chris Wallace said:

You can do this:

<link id="pageStyle" runat="server" type="text/css" rel="stylesheet"/>

protected System.Web.UI.HtmlControls.HtmlGenericControl pageStyle;

pageStyle.Attributes.Add("href", "style.css");
# October 31, 2005 2:03 PM

Jeffrey Palermo said:

I favorite method I like is open v2.0 binaries in Reflector to get an idea of how to do it.

I make <head id="myHead" runat="server"/> a server control. Then using an HtmlGenericControl, I can add anything inside it.
# October 31, 2005 4:09 PM

Peter's Gekko said:

Thanks to the great feedback on my last post on Response.AppendHeader I'm beginning to see some light....
# October 31, 2005 4:17 PM

Daniel F said:

Yeah, what daughtkom said. Get yourself a copy if iehttpheaders - http://www.blunck.info/iehttpheaders.html - and have a giggle at where the stylesheet ends up.

I've done both what Chris and Jeffery suggest too in different projects. Really depends how much you need to mess with the head.
# October 31, 2005 8:48 PM

pvanooijen said:

To make the header control a serverside control on the page requires modifying every existing page. Which is something I do want to avoid.

The stylesheet link does not have to be part of the page header, it can be in an usercontrol as well. It's in a literal control (<head in markup would have worked just as well) now and works fine.

The iehttpheaders toolbar deals with http headers, a stylesheet is an html header. Had me confused as well. It fails to install when you have FF as default browser. Pitty.
# November 1, 2005 3:05 AM

Peter's Gekko said:

A web page in in VS 2005 is assembled from several source files. Two of them are visible in VS: the markup...
# November 2, 2005 4:15 AM

Peter's Gekko said:

A web page in in VS 2005 is assembled from several source files. Two of them are visible in VS: the markup...
# November 2, 2005 10:38 AM

Zhaph said:

Most browsers will automatically just look for an item called "favicon.ico" in the root of your website - as you'll see from you logs - if you've not got one, then it will probably be the resource generating the most 404 errors!

Bear in mind that the MSDN article you've linked to refers to IE5 - it's somewhat out of date now.

Just stick the icon in the root folder of your site, and the browsers will pick it up and display it where ever the html page icon's currently displayed.

Firefox picks the icon up and displays it without any other actions required, Internet Explorer requires you to add the site to your Favorites before it looks for it.

Hth
# November 3, 2005 7:03 AM

Brad Vincent said:

what i have done in the past is use : <head runat="server" id="pageHead" />. Then u can access it from code. To avoid having to change in all pages, create a master page with the above html in, and do the change in the code behind the master page. Then make all your pages use the master page
# March 13, 2006 8:24 AM

Dave M. said:

A low tech solution to your style sheet issue:  with the project open in VS, you can do a Find and Replace on all files in the project -- all pages will be changed in under 1 minute.

# October 19, 2006 1:23 PM

pvanooijen said:

@ Dave. No, that's not maintainable software.

I'm very happy with server-side headers in 2005:

http://codebetter.com/blogs/peter.van.ooijen/archive/2005/11/02/134127.aspx

For the 2003 werstling in the stylesheet ref still works

http://codebetter.com/blogs/peter.van.ooijen/archive/2004/01/28/6203.aspx

# October 19, 2006 2:21 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!

This Blog

Syndication

News