RSS 2.0 Feed
RSS 2.0


Atom 1.0 Feed
Atom 1.0

  Creating Tracking Images for ASP.NET 


Often with web applications you want to track traffic statistics to get a general idea of the number of visitors viewing a resource. Whether it be a web page, an RSS feed, an e-mail or whatever, you might want an inconspicuous way to determine that it has been "viewed". A common tactic for tracking visitors is the use of what is known as web bugs. Web bugs are small 1x1 pixel images that will be put on a web page or e-mail that will log information about the requestor each time it is requested or consumed.

Creating web bugs, or tracking images, in ASP.NET is easy and really does not require much effort. You just create a webform (aspx) that writes the byte array of the image to the response stream and sets the content type to "image/gif". There are few other things to take into account to make the information a little more accurate, such as using the If-Modified-Since header to limit the frequency of logging the resource visit, such as only recording the visit if the page has been not been viewed by a particular visitor within the last 24 hours, and otherwise sending back an HTTP status 304 ("not modified" status for a conditional GET) so you're not duplicating visit counts from quick clicks or repeats within the last 24 hours.

Let's take a look. What we'll do in this sample is use a static byte array that will represent a 1x1 pixel image (got that idea from .Text and is an easy route to take). You could create a byte array to represent any image you wanted, but we'll just keep it simple.


public class ResourceTrack : System.Web.UI.Page
{
    private static byte[] _imgbytes =
            Convert.FromBase64String("R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==");
    
    override protected void OnInit(EventArgs e)
    {
        this.Load += new System.EventHandler(this.Page_Load);
    }

    private void Page_Load(object sender, System.EventArgs e)
    {
        // check if-modified-since header to determine if we 
        // should log again or send back a not modified result
        if (useCached(this.Context.Request))
        {
            Response.StatusCode = 304;
            Response.SuppressContent = true;
        }
        else
        {
            // add code to log visit here
            // such as write to a database

            Response.ContentType = "image/gif";
            Response.AppendHeader("Content-Length", _imgbytes.Length.ToString());
            Response.Cache.SetLastModified(DateTime.Now);
            Response.Cache.SetCacheability(HttpCacheability.Public);
            Response.BinaryWrite(_imgbytes);
        }
    }
    
    private bool useCached(HttpRequest req)
    {
        string ifmod = req.Headers["If-Modified-Since"];
        return ifmod == null ? false : DateTime.Parse(ifmod).AddHours(24) >= DateTime.Now;
    }
}


Simple enough. Now you can add that page just as you would any regular image.


<img src="http://www.mysite.com/ResourceTrack.aspx" width=1 height=1>


That's great, but what if you need additional information? Keep in mind that this "image" is really just an aspx webform. You can get to whatever you need. If you need to collect the IP address, user agent, or whatever you can get to it. Also, you can even pass values to it in the QueryString to keep track of things such as an article or user ID. You'd just have to build in the ability to look for the value in the QueryString, then you'd just add it to the URI for the source of the image tag.


<img src="http://www.mysite.com/ResourceTrack.aspx?someid=34&otherid=78" width=1 height=1>


I use this kind of thing in RSS feeds from some of my websites to track the aggregate views and to track page views on a few sites also. To track counts for RSS feeds, I just add the image into the item description, ala .Text style. Works great. However, there are some things to consider when using this approach. If you are using web bugs in e-mails then you might as well forget it. This is a common approach taken by spammers to verify a valid e-mail address so e-mail clients, such as Outlook 2003, won't download images into the e-mail body by default. Your web bug image never gets pulled from the server so you won't get accurate counts logged. Most RSS readers will pull the images by default, however some do have options (such as RSS Bandit) to not pull down images from a post. I do think it is the best route for tracking RSS feed items (at least until something better comes along). For use on web pages, it would be a safe bet since the page will serve up images aleady.




                   



Leave a comment below.

Comments

  1. Gravatar
    A nice idea, but surely it would make more sense to create a custom HTTP handler instead? This would remove the unneccessary (in this case) overhead involved in the ASP.NET Page lifecycle. Especially since this page will be called very frequently.
  2. Ryan Farley 6/11/2004 7:41 AM
    Gravatar
    Ben, I agree, and that is actually how I do this in my own applications (but wanted to keep things as simple as possible for this sample). I plan on doing another post on HttpHandlers in the future, I'll make sure to tie it back to this post to complete the best-base picture. Thanks.
  3. Kieron 5/12/2005 7:34 AM
    Gravatar
    Hi Ben, I've been using the same technique recently as I need to track a site on a different server to my own and so wouldn't have been able to develop in .NET, which is my preference if i'd developed the tracking on the other server. Everything is fine, but i'd really like to be able to use a cookie served with the web bug to give more reliable post click tracking, but I can't get it to work. The cookie is never written.

    Is this possible and if so how is it done?

    Thanks in advance.
  4. Swathi 5/15/2006 12:37 PM
    Gravatar
    I am implementing this on my work web site. The page on which the tracker page is being used shows the tracker page as a bad image (red-x). Is it supposed to work that way? Is that the reason why the image height and width are set to 1?
  5. Ryan Farley 5/15/2006 12:40 PM
    Gravatar
    Swathi.

    No it is not supposed to look that way. If that is happening then something is not working.

    -Ryan
  6. Swathi 5/15/2006 10:30 PM
    Gravatar
    Thanks for the quick response. However, I still could not figure out what was going wrong. Here’s what I have:
    - A main tracker class, called MasterTracker.vb inheriting from System.Web.UI.Page.
    - TestTracker.aspx inheriting from the MasterTracker class (we need to make use of the tracker class in several web pages on the site … all the tracker pages inherit from MasterTracker class)
    - A web page (aspx page) example default.aspx, in which the tracker page is used

    MasterTracker.vb: The following 2 routines make up MasterTracker.vb class

    1. fGetImgByteArray(), which returns a byte array that represents a 1x1 pixel image. The function reads the 1x1 pixel gif image off the file stream into a Byte array, and then passes it into a public property of a serializable class Tracker.vb. This class's object is then serialized using BinaryFormatter and the function returns the resultant byte array.

    2. fResponse(), which sets the response content type to "image/gif", grabs the byte array of the image obtained from the above function and then writes the byte array to the response stream. This sub is then called in the page load of MasterTracker class.

    TestTracker.aspx: is a simple aspx page, inheriting from MasterTracker.vb. It does not have a code behind file. I just have the page directive of TestTracker.aspx as follows:
    <%@ Page Language="vb" Inherits="MasterTracker" %>

    default.aspx: is the page on which the 1x1 pixel tracker is being used i.e,
    <img src="TestTracker.aspx" height="1" width="1">

    Now, everything seems to get logged properly, I checked it in my Temporary Internet Files and it shows tracker page TestTracker.aspx as a gif image, but when I do not specify height and width in the img tag i.e.,
    <img src="TestTracker.aspx">,
    I am getting an image not available on the page. (Not to mention ... it is the same case when height="1" width="1" is specified in the image tag, just that you can’t see that it’s a bad image because of the small size).
    Can you please tell why this might be happening?

    Thanks in advance.
  7. Swathi 5/19/2006 4:29 PM
    Gravatar
    I figured it out what was wrong.

    Thanks and regards
  8. Fred 11/9/2006 12:44 PM
    Gravatar
    Ryan,
    What would be a good way to track emails open? How does an emaillabs track? We would like to track what current customers open up a newletter email or not. The unsubscribe and other click thrus are easy, but what if they open the email and just close? Any good ideas?
  9. arby 3/31/2008 7:32 AM
    Gravatar
    Quick question..... a lot of email clients block images from being downloaded so that even though an email is "opened", unless the user downloads the images, doesn't that throw off your stats?

    Any suggested solutions for this problem?

  10. webbie 7/11/2008 6:09 AM
    Gravatar
    Hey Swathi...

    I'm facing the same problem which you've mentioned..(getting a bad image when I specify height="1" and width="1"). How did you fix that? Please let me know.

    Thanks,
    webbie
  11. Krishnan 8/5/2008 10:35 PM
    Gravatar
    How to track the forwarded and spam emails.
  12. Bishoy Rasmy 12/18/2008 3:38 PM
    Gravatar
    i Need to know how retrive an image from sql DB(image datatype) to an image control in aspx web page
    and thanks

    if you got a selution please send it to
    pop_lool_85@hotmail.com
  13. Ajay Reddy 6/14/2010 11:58 PM
    Gravatar
    Its Nice and working fine. we can use
    HttpContext.Current.Request.UrlReferrer.xxx

    properties to get the detail information.
    Thanks.

  14. samir 8/4/2010 5:38 AM
    Gravatar
    Hello Ryan,

    Nice Article , But what if user not clicking display images below???


    thanxx in advance...

    regards,
    samir
  15. Ryan Farley 8/4/2010 10:19 AM
    Gravatar
    Samir,
    The user doesn't need to click the image. The fact that the image loads is what give you opportunity to track it.

    -Ryan
Comments have been closed on this topic.



 

News


Also see my CRM Developer blog

Connect:              


Sponsor

Sections