Tracking download of non-html (like pdf) downloads with jQuery and Google Analytics

10 Oct

Hi folks, it’s been quite calm at Developer IT’s this summer since we were all involved in other projects, but we are slowly comming back.

In this post, we will present a simple way of tracking files download with Google Analytics with the help of jQuery. We work for a client that offers a lot of pdf files to download on their web site and wanted to know which one are the most popular. They use Google Analytics for a long time now and we did not want to have a second interface in order to present those stats to our client. So usign IIS logs was not a idea to consider.

Since Google already offers us a splendid web interface and a powerful API, we deceided to hook up simple javascript code into the jQuery click event to notify Analytics that a pdf has been requested.

(function ($) {
    function trackLink(e) {
        var url = $(this).attr('href');
        //alert(url); // for debug purpose
        // old page tracker code
        // you can use the new one too
       //always return true, in order for the browser to continue its job
        return true;

   // When DOM ready
    $(function () {
        // hook up the click event
        $('.pdf-links a').click(trackLink);

You can be more presice or even be sure not to miss one click by changing the selector which hooks up the click event. I have been usign this code to track AJAX requests and it works flawlessly.

C# development with Mono and MonoDevelop

7 May

In the past two years, I have been developing .NET from my MacBook by running Windows XP into VM Ware and more recently into Virtual Box from OS X. This way, I could install Visual Studio and be able to work seamlessly.

But, this way of working has a major down side: it kills the battery of my laptop… I can easiely last for 3 hours if I stay in OS X, but can only last 45 min when XP is running.

Recently, I gave MonoDevelop a try for developing Developer IT‘s tools and web site. While being way less complete then Visual Studio, it provides essentials tools when it comes to developping software. It works well with solutions and projects files created from Visual Studio, it has Intellisence (word completion), it can compile your code and can even target your .NET app to linux or unix. This tools can save me a lot of time and batteries!

Although I could not only work with MonoDevelop, I find it way better than a simple text editor like Smultron. Thanks to Novell, we can now bring Microsoft technology to OS X.

More than 100,000 articles !

13 Apr

In one month, we already got more than 100,000, and we continue to crawl! We plan on hitting 250,000 total articles next month.

Due to the large amount of data we are gathering, we are planning on updating our SQL stored procedure to improve performance. We may be migrating to SQL Server 2008 Entreprise, as we are currently running on SQL Server 2005 Express Edition… We are at 400 Mb of data, getting more and more close to the 2 Gb limit.

Stay tune for more info and browse daily fresh articles about web development.

Official BETA release of Developer IT

17 Mar

We finally did it

It’s been a week since our first online publish and our indexer robot is going as well as the website. We already have reach more than 20,000 articles and it’s only the begining.

Stay tune on

How to get full query string parameters not UrlDecoded

17 Mar


While developing Developer IT’s website, we came across a problem when the user search keywords containing special character like the plus ‘+’ char. We found it while looking for C++ in our search engine. The request parameter output in ASP.NET was “c “. I found it strange that it removed the ‘++’ and replaced it with a space…


After a bit of Googling and Reflection, it turns out that ASP.NET calls UrlDecode on each parameters retreived by the Request(“item”) method. The Request.Params property is affected by this two since it mashes all QueryString, Forms and other collections into a single one.


Finally, I solve the puzzle usign the Request.RawUrl property and parsing it with the same RegEx I use in my url re-writter. The RawUrl not affected by anything. As its name say it, it’s raw.

Published on

How to obtain a random sub-datatable from another data table

13 Mar


In this article, I’ll show how to get a random subset of data from a DataTable. This is useful when you already have queries that are filtered correctly but returns all the rows.


I came across this situation when I wanted to display a random tag cloud. I already had the query to get the keywords ordered by number of clicks and I wanted to created a tag cloud. Tags that are the most popular should have more chance to get picked and should be displayed larger than less popular ones.


In this code snippet, there is everything you need.
See the full source code here at


This method is good because it doesn’t require much work to get it work fast. It is a good concept when you are working with small tables, let says less than 100 records.


If you have more than 100 records, out of memory exception may occur since we are coping and duplicating rows. I would consider using a stored procedure instead.

Published on

Remove accents from String .NET

12 Mar

Private Const ACCENT As String = “ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÌÍÎÏìíîïÙÚÛÜùúûüÿÑñÇç”
Private Const SANSACCENT As String = “AAAAAAaaaaaaOOOOOOooooooEEEEeeeeIIIIiiiiUUUUuuuuyNnCc”
Public Shared Function FormatForUrl(ByVal uriBase As String) As String
If String.IsNullOrEmpty(uriBase) Then
Return uriBase
End If

‘// Declaration de variables

Dim chaine As String = uriBase.Trim.Replace(” “, “-“)

chaine = chaine.Replace(” “c, “-“c)

chaine = chaine.Replace(“–“, “-“)

chaine = chaine.Replace(“‘”c, String.Empty)

chaine = chaine.Replace(“?”c, String.Empty)

chaine = chaine.Replace(“#”c, String.Empty)

chaine = chaine.Replace(“:”c, String.Empty)

chaine = chaine.Replace(“;”c, String.Empty)

‘// Conversion des chaines en tableaux de caractŠres

Dim tableauSansAccent As Char() = SANSACCENT.ToCharArray

Dim tableauAccent As Char() = ACCENT.ToCharArray

‘// Pour chaque accent

For i As Integer = 0 To ACCENT.Length – 1

‘ // Remplacement de l’accent par son ‚quivalent sans accent dans la chaŒne de caractŠres

chaine = chaine.Replace(tableauAccent(i).ToString(), tableauSansAccent(i).ToString())


‘// Retour du resultat

Return chaine

End Function

Published at from

Good SQL error handling in Strored Procedure

11 Mar

When writing SQL procedures, it is really important to handle errors cautiously. Having that in mind will probably save your efforts, time and money. I have been working with MS-SQL 2000 and MS-SQL 2005 (I have not got the opportunity to work with MS-SQL 2008 yet) for many years now and I want to share with you how I handle errors in T-SQL Stored Procedure. This code has been working for many years now without a hitch.

N.B.: As antoher “best pratice”, I suggest using only ONE level of TRY … CATCH and only ONE level of TRANSACTION encapsulation, as doing otherwise may not be 100% sure.

See the full article and source code at

In conclusion, I will just mention that I have been using this code with .NET 2.0 and .NET 3.5 and it works like a charm. The .NET TDS parser throws back a SQLException which is ideal to work with.
Published on

Fake ISAPI Handler to serve static files with extention that are rewritted by url rewriter

10 Mar


I often map html extention to the dll in order to use url rewritter with .html extentions. Recently, in the new version of, we renamed all urls to end with .html. This works great, but failed when we used FCK Editor. Static html files would not get serve because we mapped the html extension to the .NET Framework. We can we do to to use .html extension with our rewritter but still want to use IIS behavior with static html files.


I thought that this could be resolve with a simple HTTP handler. We would map urls of static files in our rewriter to this handler that would read the static file and serve it, just as IIS would do.


This is how I coded the class. Note that this may not be bullet proof. I only tested it once and I am sure that the logic behind IIS is more complicated that this. If you find errors or think of possible improvements, let me know.

See the full source code and article at


As you see, with our static files map to this handler using query string (ex.: /ISAPIDotNetHandler.ashx?fileUri=index.html) you will have the same behavior as if you ask for the uri /index.html.

Finally, test this only in IIS with the html extension map to aspnet_isapi.dll. Url rewritting will work in Casini (Internal Web Server shipped with Visual Studio) but it’s not the same as with IIS since EVERY request is handle by .NET.


  1. First release

Published on