Sunday, May 16, 2010

How to include JavaScript tracking code into head control in asp.net

Google Analytics team recommends to include Asynchronous Google Analytics tracking javascript code right before closing </head> tag.
So, how to include that script into every page on your web site without modifying every page?

I considered multiple solutions:

1) Cut&paste into every page (the worst).

2) Create HeadScriptControl.cs server control and cut&paste it into every page (slightly better, but still requires lots of cut&paste).
Here's an example of HeadScriptControl code:
using System;
using System.Web.UI;
using System.Text;

public class HeadScriptControl : Control
{
private const string GoogleAnalyticsFirtsPartScript = @"
<script type=""text/javascript"">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-XXXXXX-2']);
_gaq.push(['_trackPageview']);
</script>
";
protected override void Render(HtmlTextWriter writer)
{
writer.Write(GoogleAnalyticsFirtsPartScript);
}
}

3) Create PageWithHeadScript.cs, inherit it from Page control, inherit every page on your web site from PageWithHeadScript.cs and render HeadScriptControl in PageWithHeadScript.cs like this:
public class PageWithHeadScript : Page
{
protected override void Render(HtmlTextWriter writer)
{
this.Header.Controls.Add(new HeadScriptControl());
base.Render(writer);
}
}
That approach requires even less cut&paste, but still every page on your web site needs to be touched.

4) Using HttpHandler.
I think that's the best approach, because it's not necessary to modify pages at all.
Here’s how I do it.

4.1. Create HttpModule:
public sealed class MyHttpModule : IHttpModule
{
void IHttpModule.Init(HttpApplication application)
{
application.PreRequestHandlerExecute += new EventHandler(application_PreRequestHandlerExecute);
}

void application_PreRequestHandlerExecute(object sender, EventArgs e)
{
RegisterPagePreRenderEventHandler();
}
private void RegisterPagePreRenderEventHandler()
{
if (HttpContext.Current.Handler.GetType().ToString().EndsWith("_aspx"))
{ // Register PreRender handler only on aspx pages.
Page page = (Page)HttpContext.Current.Handler;
page.PreRender += new EventHandler(page_PreRender);
}
}

void page_PreRender(object sender, EventArgs e)
{
System.Web.UI.Page page = (Page)sender;
page.Header.Controls.Add(new PostJobFree.WebUI.Controls.HeadScriptControl());
}

void Application_BeginRequest(object sender, EventArgs e)
{
DosAttackAnalyzer.AnalyzeHttpRequest(Ijs.Misc.BrowserIPAddress);
// DenyIpAddress.DenyAccessToCurrentIpAddressIfBlacklisted();
}
void IHttpModule.Dispose()
{
}
}

4.2. Register HttpModule in web.config:
<?xml version="1.0"?>
<configuration>
<system.webServer>
<modules>
<remove name="DenyIpAddressModule"/>
</modules>
</system.webServer>
</configuration>
</pre>

Note that it's impossible to add controls into page straight in PreRequestHandlerExecute event handler.
That's why I subscribe for Page.PreRender event.

Please let me know what you think.

No comments:

Followers

About Me

My photo
Email me: blog@postjobfree.com