Web Analytics/Media Tagging on ASP.net AJAX Pages

More often than not a site build is deployed with little focus on analytics or any kind of measurement in mind- or, if it was; it was built against a moving target which is now little help to the current needs for site-tagging to facilitate your marketing goals.

A common scenario I see regularly is a checkout process and/or registration with a form and confirmation all at the same page location (“Checkout.aspx” or “Registration.aspx”).  How are you supposed to get in later without going back to the site build in order to get your conversion tags on just one page or another? (Un?)Fortunately for you, it was built in ASP.net and no matter how poorly it may or may not have been done, there’s a good chance with minimal code you’ll be able to deploy your tags to the page-states they need to be.

Enough with the blah:

  • You have a tag that you can load arbitrary Javascript on the page
  • Can’t distinguish by page URL alone
  • Tag fires either once per process, or each step in the process.

Any ASP.net site I’ve seen since ASP.net 2.0 and later have the decently-rich ASP.net AJAX API loaded by default (I don’t think you need to be utilizing any actual ASP.net AJAX functionality, as the validators all use this code too).  There are many objects and methods within the Sys.Application javascript object, that ASP.net has so nicely exposed for the rest of us – however lesser known unless you’re doing some client-side hacking.

The two events/handlers/methods that will be most useful are the pageLoad, and pageInit.

Init: http://msdn.microsoft.com/en-us/library/bb397532.aspx
Load: http://msdn.microsoft.com/en-us/library/bb383829%28loband%29.aspx

There are two ways to utilize these client-side events:

Override with your own methods
If you are familiar with the ASP.net page lifecycle events, you’ll see a simliar structure. And you can bet the same or similar structure exists on the client-side as well. By creating functions with specific names that map to the ASP.net events, you can run specific code when each happens, and have access to the javascript representation of the event itself, and event sender.

    function pageLoad(sender, eventArgs){
        //code to be triggered client side
        //synonymous to ASP.net Page_Load
    }

    function pageInit(sender, eventArgs){
        //code to be triggered client side
        //synonymous to ASP.net Page_Init
    }

The unobtrusive way
The ASP.net AJAX javascript API provides nice methods to attach and detach handlers to their ASP.net page lifecycle events.

    function myInit(){
        //my pageInit code
    }

    //register handler
    Sys.Application.add_init(pageInit);

    //using anonymous functions
    Sys.Application.add_load(function(){
        // my pageLoad code
    });

In this solution below, I have a two-step process (form, confirmation) all within one full page load. A parital page post-back occurs updating the form to be the confirmation page, and only loads my tag that I’m loading the javascript through once. On the confirmation page there is a div that gets loaded with an ID of “distingushingID” into the mark up that does not exist on the registration form markup. In this scenario I’m either too late or can’t utilize Page_Load, so I have to rely on Page_Init which loads each postback, partial or not. I imagine you’ll need some trial and error to find the right event.

Sys.Application.add_init(function(){
    var newFrame = document.createElement('iframe');
    newFrame.style.display='none';
    newFrame.style.width='1px';
    newFrame.style.height='1px';
    if(document.getElementById("distinguishingID")){
        newFrame.src = document.location.protocol + '//fls.doubleclick.net/activityi;src=1234567;type=type123;cat=cat456;ord=1;num=' + Math.random();
    }else{
        newFrame.src= document.location.protocol +  '//fls.doubleclick.net/activityi;src=1234567;type=type345;cat=cat789;ord=1;num='+ Math.random();
    }
    document.getElementsByTagName('body')[0].appendChild(newFrame);
});

Leave a Reply

Your email address will not be published. Required fields are marked *