Project Description

No more 'Ctl F5'. The file timestamp extensions are set of ASP.NET controls that append a timestamp to relative paths of files (eg: images, stylesheets, documents) so client browsers will always load any changed files rather than using old cached versions.

The one thing I hate is clients saying that the style of Web pages are out of sync, or that we are still using the old image. And I have to say the usual 'Please press Control F5' to reload the page. It is not a problem until they ask whether all their clients have this issue too....

Now we tag the images and StyleSheets with a timestamp so when they change, clients will 'always' see the change too. And this library makes it automatic - no need to think about which images have changed, or where they are referenced.

If this happens to you, please (by all means) make use of the controls, and let us know if you have any problems, or other controls that need extending.
For us these controls have become the standard image and link controls!

Library Controls

There are 5 ASP.NET Controls in this library that automatically append a timestamp to the relative path to (static) files that are cached on the client eg: images, stylesheets and documents.
  1. Image (Perceiveit.Web.UI.WebControls.Image, Extends System.Web.UI.WebControls.Image). Timestamps the ImageUrl property for local (relative) files
  2. ImageButton (Perceiveit.Web.UI.WebControls.ImageButton, Extends System.Web.UI.WebControls.ImageButton). Timestamps the ImageUrl property for local (relative) files
  3. HyperLink (Perceiveit.Web.UI.WebControls.HyperLink, Extends System.Web.UI.WebControls.Hyperlink). Timestamps the ImageUrl property for local (relative) files
  4. FileLink (Perceiveit.Web.UI.WebControls.FileLink, Extends Perceiveit.Web.UI.WebControls.Hyperlink). Timestamps the ImageUrl property and the NavigateUrl property for local (relative) files
  5. StyleSheet (Perceiveit.Web.UI.WebControls.StyleSheet, Extends System.Web.UI.Contol). Renders a link tag to a stylesheet, again adding the timestamp to the query string.

All the controls have a UseTimeStamp property which can be used to turn off and on the behaviour - however the default is true.
When a referenced file is modified or replaced at runtime, the new output for the page will use an updated timestamp automatically.
No need to do anything else. All users will see the new file(s) immediately.

Because all the controls inherit from standard WebControls (except StyleSheet), there is no learning curve. Just register the assembly on the page or in web config, and change your current image prefixes. Simple.

Source Example

ASPX Page markup

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly="Perceiveit.Web.TimeStampControls" Namespace="Perceiveit.Web.UI.WebControls" TagPrefix="pit" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <!-- the stylesheet -->
    <pit:StyleSheet ID="StyleSheet1" runat="server" CssUrl="styles/MyStyles.css" MediaTypes="All" ></pit:StyleSheet>
</head>
<body>
    <form id="form1" runat="server">
    <div class="divider">
        <!-- the image -->
        <pit:Image runat="Server" ID="AnImage" ImageUrl="images/Smiley_Face.gif" />
    </div>
    <div class="divider">
        <!-- the image button -->
        <pit:ImageButton runat="server" ID="AnImageButton" ImageUrl="images/Smiley_Face.gif" />
    </div>
    <div class="divider">
        <!-- the hyperlink -->
        <pit:HyperLink runat="server" ID="AHyperLink" ImageUrl="images/Smiley_Face.gif" NavigateUrl="Default.aspx" />
    </div>
    <div class="divider">
        <!-- the file link -->
        <pit:FileLink ID="FileLink1" runat="server" NavigateUrl="~/images/Smiley_Face.gif">Link to a stamped file</pit:FileLink>
    </div>
    <div class="reloadpanel">
        <a href="Default.aspx" >Reload</a>
    </div>
    </form>
    
</body>
</html>


Rendered Output

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>
	Untitled Page
</title>
         <!-- the stylesheet -->
         <link id="StyleSheet1" type="text/css" media="all" rel="Stylesheet" href="styles/MyStyles.css?t=633847008962187500"/></head>
<body>
    <form name="form1" method="post" action="Default.aspx" id="form1">
<div>
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEP...Bj+Hg==" />
</div>

    <div class="divider">
        <!-- the image -->
       <img id="AnImage" src="images/eip_save.gif?t=633328915880000000" style="border-width:0px;" />
    </div>
    <div class="divider">
        <!-- the image button -->
        <input type="image" name="AnImageButton" id="AnImageButton" src="images/eip_save.gif?t=633328915880000000" style="border-width:0px;" />
    </div>
    <div class="divider">
        <!-- the hyperlink -->
        <a id="AHyperLink" href="Default.aspx"><img src="images/eip_save.gif?t=633328915880000000" style="border-width:0px;" /></a>
    </div>
    <div class="divider">
        <a id="FileLink1" href="images/eip_save.gif?t=633328915880000000">Link to a stamped file</a>
    </div>
    <div class="reloadpanel">
        <!-- the file link -->
        <a href="Default.aspx" >Reload</a>
    </div>
    
<div>

	<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wE...Kkw=" />
</div></form>
    
</body>
</html>


Note the '?t=...' at the end of the image and stylesheet refs. This means that if any of these referenced files are modified, the timestamp value will change and the browser will automatically reload the new content from the server, this even works for print StyleSheets.

Performance and extensibility

The main logic for the timestamp is contained in the abstract TimeStampProvider class which has a static factory method GetFileProvider(). Using this allows TimeStampProviders to be stored in the HttpCache for rapid retrieval, and it also means that if there are existing controls you wish to add this timestamp functionality too, then use this method call to get a valid instance. Other implementations could also extend to support other file storage mechanisms.

Last edited Aug 5, 2009 at 9:57 PM by perceiveit, version 26