Click here to Skip to main content
16,012,611 members
Articles / Web Development / ASP.NET

Custom Control Displays 'Last Modified' Date/Time on Your Web Pages

Rate me:
Please Sign up or sign in to vote.
2.40/5 (2 votes)
5 Apr 2009CPOL5 min read 50.9K   376   23   4
A very simple Custom Control displays Date/Time a page (*.aspx file) was last modified. Drops into Toolbox and works at design-time.

Add "Last Modified" Date/Time to Your Web Pages

Sample image

Introduction

Using the simple custom control here, you can display the date/time your web pages were last modified (such as in my web page footer above). Showing the date of modification might give your viewers an idea of how current the information contained on the page is.

This project also serves as an example of creating a simple custom control. The control drops right into the Toolbox in Visual Studio (or Visual Web Developer) and can be used at design-time or is extremely simple to edit manually into your pages.

Including the control in your master page will add the "Last Modified" date/time to all your web pages.

Using the Code

All you need to do to use the LastModified control is to include it in your web page code:

ASP.NET
<Tek4:LastModified runat="server" />

The above only generates the date and time, therefore, you may wish to provide some sort of label and/or enclosing <span> or <div> for styling:

ASP.NET
<span style="font-size:smaller;">
  LastModified: <Tek4:LastModified runat="server" />
<span>

If you want to change the default DateTime format string (see below), specify the additional Format property:

ASP.NET
<Tek4:LastModified runat="server" Format="g" />

Also, you must copy the Tek4.Web.UI.CustomControls.LastModified.dll assembly to your web application's /bin directory, or, install it into the GAC (Global Assembly Cache).

Finally, you will need to register the assembly at the top of your web page:

ASP.NET
<%@ Page %>
<%@ Register TagPrefix="Tek4"
 Namespace="Tek4.Web.UI.CustomControls.LastModified"
 Assembly="Tek4.Web.UI.CustomControls.LastModified,
 Version=1.0.0.1, Culture=neutral, PublicKeyToken=26c804c56bafc725" %>

Or, alternatively, you can keep your pages free of clutter and register the assembly in your web.config file instead:

XML
<system.web>
    <pages>
      <controls>
        <add tagprefix="Tek4"
           assembly="Tek4.Web.UI.CustomControls.LastModified"
           namespace="Tek4.Web.UI.CustomControls.LastModified,
             Version=1.0.0.1, Culture=neutral,
             PublicKeyToken=26c804c56bafc725" />
      </controls>
    </pages>
</system.web> 

The compiled assembly included with this project is securely signed with my security key so it can be installed into the GAC. If you re-compile the project, you will need to provide your own secure key for signing. 

Adding the LastModified Custom Control to your Toolbox

To add the LastModified control to your Visual Studio (or Visual Web Developer) toolbox, simply open a file window containing the *.dll assembly and drag the assembly to the toolbox:

Image 2

The LastModified control is added next to its clock icon:

Image 3

You can now double-click or drag the LastModified control to your web page in design view:

Image 4

Here is the properties window for the LastModified control:

Image 5

The only unique property of the LastModified control is the Format property which is a string that dictates the date/time format used for rendering the control (see below). The default value is 'r'.

DateTime Format Property

The output format for the Date/Time is dictated by the Format property. The Format property is a standard .NET DateTime format string of which there are two categories:

Standard DateTime Format Strings

Standard DateTime Format Strings consist of a single character format specifier that represents a custom format. Examples are:

  • d - Short Date (MM/dd/yyyy)
  • D - Long Date (dddd, dd MMMM yyyy)
  • f - Full Date/Time (dddd, dd MMMM yyyy HH:mm)
  • g - General Date/Time (MM/dd/yyyy HH:mm)
  • r - RFC1123 Pattern (ddd, dd MMM yyyy HH':'mm':'ss 'GMT')

The default format is 'r' and will be used if you do not specify the Format property.

Remember, if you are using a Standard DateTime Format String, the actual displayed format is determined by the current culture of the web server as set in the Regional and Language Options in the Control Panel. The culture does not affect the default RFC1123 format, however.

Custom DateTime Format Strings

Custom DateTime Format Strings consist of a pattern of characters that allow you to display the date and time in any manner you choose. Examples are:

  • d MMMM - (12 April)
  • dddd MMMM yy gg - (Thursday April 01 A.D.)
  • hh:mm, G\MT zzz - (05:13 GMT -09:00)

Refer to the MSDN Documentation on DateTime Format Strings for formulating your own formats. 

Points of Interest  

The actual code is very simple. The LastModified class inherits from System.Web.UI.WebControls.WebControl which serves as the base class for all WebControls. On it's own, WebControl simply renders as an empty set of <span> tags:

ASP.NET
<span></span>

The LastModified class overrides a single method of WebControl: The RenderContents() method. The RenderContents() method is responsible for all of a control's content between its opening and closing tags—the content that will be rendered between the <span> tags.

RenderContents() is passed an HtmlTextWriter object that is used for rendering. Upon invocation, RenderContents() defines a DateTime object, dt, that will receive the last modified date/time. Entering a try block to protect against exceptions, the file path of the current *.aspx page is retrieved by first obtaining the virtual web path, then converting it to a file system path using MapPathSecure().

C#
protected override void RenderContents(HtmlTextWriter writer) {
  DateTime dt;
  try {
    string filePath = MapPathSecure(Page.Request.CurrentExecutionFilePath);
    dt = new FileInfo(filePath).LastWriteTime;
  } catch { // "design-time" or current path doesn't resolve to a file
    dt = DateTime.Now;
  }
  writer.Write("{0:" + Format + "}", dt);
}

To obtain the virtual web path of the currently executing script, we access the CurrentExecutionPath property of the current page's Request object. This operation will throw an exception if we are using the control at design-time in Visual Studio because there is no Request object. There are subtle differences between the Request object's CurrentExecutionPath, Path, and FilePath properties—review the MSDN Documentation for specifics—but know that the CurrentExecutionPath property yields a virtual path to the actual executing script with no additional trailing strings.

A FileInfo object constructed with the file path yields its LastWriteTime property—our "Last Modified" DateTime object. The catch block initializes dt with the current date/time in the event of exceptions (such as during design-time.)

Final output rendering is simply a write to the HtmlTextWriter object using the formatting specified by the Format property.

Class Attributes

Looking at the class declaration in the code reveals quite a few attributes that are applied:

C#
[ AspNetHostingPermission(SecurityAction.Demand,
    Level = AspNetHostingPermissionLevel.Minimal),
  AspNetHostingPermission(SecurityAction.InheritanceDemand,
    Level = AspNetHostingPermissionLevel.Minimal),
  DefaultProperty("Format"),
  ToolboxData("<{0}:LastModified runat="\""server\"/>") ]
public class LastModified : WebControl {

In brief, the AspNetHostingPermission attributes demand the minimum trust level the code needs to execute in an ASP.NET hosting environment. The other two attributes are for Visual Studio's design-time. DefaultProperty specifies that the one-and-only property, Format, is the default to use during design. The ToolboxData attribute specifies the web page code inserted by Visual Studio by default.

Format Property

This property allows getting and setting the format of the date/time output. The format string is saved in the control's ViewState. The default value of 'r' is returned if nothing is set. Multiple attributes specify design-time properties for Visual studio.

C#
[ Bindable(true),
  Category("Appearance"),
  DefaultValue("r"),
  Description("A DateTime format specifier.")    ]
public virtual string Format {
  get {
    string s = (string)ViewState["Format"];
    return (s == null) ? "r" : s;
  }
  set {
    ViewState["Format"] = value;
  }
}

History  

  • 2007-02-11 v.1.0.0.0 - Original post
  • 2009-04-05 v.1.0.0.1 - Added AllowPartiallyTrustedCallers attribute

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Kevin Rice is a firefighter for a major Southern California fire department. When not working, he enjoys web programming, administration, riding dirt-bikes (Visit SLORider.com) or building anything electronic.

Comments and Discussions

 
QuestionShort way Pin
Emad Al Hawary12-Sep-12 3:32
Emad Al Hawary12-Sep-12 3:32 
GeneralNew problem with this control Pin
Geepster7-Apr-08 12:30
Geepster7-Apr-08 12:30 
Kevin -
I've been successfully using this control while prototyping a federal government site, but as you may know we've recently had new security imposed on all desktops, called FDCC. This is causing a problem for me with your control (among others)... when my Visual Studio 2005 web site project loads, it reports (for each problematic 3rd-party DLL):

“The proper type library could not be found in the system registry.
An attempt to repair this condition failed because you do not have the permissions to write to the system registry or because the type library could not be loaded.”

Loading the project under my administrative account does not solve it when subsequently loaded under the regular account.

For a while, I could still build the project, even with this problem. Now I get fatal build errors (due to password change? Patch or reboot? Who knows). At least the build errors now pinpoint the dlls (including Tek4) that are the problem.

If you try regsvr32 on Tek4, you get the message “DllRegisterServer entry point was not found. This file can not be registered.”

So, following some suggestions from blogs, under my admin account, I did (not showing the full paths here):

1) Check the signature of the dlls with sn –Vr <dll name="">.dll
For Tek4, seemed to work, said “Verification Entry coded for ‘Tek4…’...", gave a code number.
2) Register the dll by doing : gacutil/I <dll name="">.dll
For Tek4, seemed to work, said “Assembly successfully added to cache”

However, when I returned to my regular account and loaded the project again, I got the usual error dialogs and the build errors once more.
- Geepster
GeneralRe: New problem with this control Pin
kriceslo7-Apr-08 16:32
kriceslo7-Apr-08 16:32 
AnswerRe: New problem with this control Pin
Geepster9-Apr-08 5:42
Geepster9-Apr-08 5:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.