ASP.NET integration module

From ClickTale Wiki
Jump to: navigation, search

ClickTale users can download and begin using this Integration module on ASP.NET 1.1 - 4.5 websites and applications . The Module's features include:

  • Automatic injection of the ClickTale script to all outgoing pages.
  • Automatic caching of page's content.

Using the Integration Module, would enable you to record pages which are dependent upon session cookies as well as pages which are processed via the POST request and pages behind a log-in. All elements which are not supported for recording via the standard tracking code.


Installation Guide

ClickTale ASP.NET Integration Module v1.7
The module is compatible with .NET 1.1 - 4.5 sites.

If you are unable to install a binary module on your site, please use the ASP.NET integration code instead.

Step 1 - Getting the archive

  • Download and unzip the module here.
***Please note: If you are using version 1.1 please install the ClickTaleIntegrationModule.dll file available in the FX1_1 folder. 
Otherwise, please install the .dll file located in the above .zip file

Step 2 - Installing the module

Method 1 -

  • Place the ClickTaleIntegrationModule.dll file in your "bin" folder. if the folder is not present on your website, please create it.

Method 2 - Only for users of ASP.NET version 2.0 or higher

  • Use Microsoft's Global Assembly Cache Tool (Gacutil) to add the ClickTaleIntegrationModule.dll file to the Global Assembly Cache (GAC) on your server.
  • Add the following line to your Web.config file, in the <assemblies> section:
<add assembly="ClickTaleIntegrationModule, Version=, Culture=neutral, PublicKeyToken=e409f4b387f2a263" />

Step 3 - Preparing the tracking code for injection

3.1  Remove the existing ClickTale code and/or disable other integration methods.
3.2  Locate the ClickTaleScripts.xml file that is part of the ZIP file and open it in a text editor.
3.3  Paste your ClickTale tracking code snippets (generated by the tracking code generator) into the appropriate CDATA fields in the XML file.
3.4  Add the cache fetching redirection code, according to your tracking code type:     (How can I find which code type my project is using?)

If you have code type Atlas, click 'Expand' below to see the instructions for placing your code. Click 'Collapse' to close the section.

Add the line:
var ClickTaleFetchFrom="http://%RootPath%/ClickTaleCache.ashx?t=%CacheToken%";

Just before the line

   if(typeof ClickTale=='function') ClickTale([your project parameters]);

Please note: You do not need to change "http://%RootPath%/ClickTaleCache.ashx?t=%CacheToken%" to a specific URL. It will be replaced automatically during the rendering process, with a value dependent on the page being recorded.
Your xml file should now look like this (Please do not copy and paste this part):

<?xml version="1.0" encoding="utf-8" ?>
<script name="Top" DoNotReplaceCondition = "&lt;!-- ClickTale Top part --&gt;">
   <!-- ClickTale Top part -->
   <script type="text/javascript">
   var WRInitTime=(new Date()).getTime();
   <!-- ClickTale end of Top part -->]]>
<script name="Bottom" DoNotReplaceCondition = "&lt;!-- ClickTale Bottom part --&gt;">
   <!-- ClickTale Bottom part -->
<div id="ClickTaleDiv" style="display: none;"></div>
<script type='text/javascript'>
   <script type="text/javascript">
   var ClickTaleSSL=1;
   var ClickTaleFetchFrom="http://%RootPath%/ClickTaleCache.ashx?t=%CacheToken%";
   if(typeof ClickTale=='function') ClickTale([your project parameters]);
   <!-- ClickTale end of Bottom part -->

If you have code type Balkan, click 'Expand' below to see the instructions for placing your code. Click 'Collapse' to close the section.

Add the line:
var ClickTaleFetchFrom="http://%RootPath%/ClickTaleCache.ashx?t=%CacheToken%";

Just before the line


Please note: You do not need to change "http://%RootPath%/ClickTaleCache.ashx?t=%CacheToken%" to a specific URL. It will be replaced automatically during the rendering process, with a value dependent on the page being recorded.
Your xml file should now look like this (Please do not copy and paste this part):

<?xml version="1.0" encoding="utf-8" ?>
<script name="Top" DoNotReplaceCondition = "&lt;!-- ClickTale Top part --&gt;">
   <!-- ClickTale Top part -->
   <script type="text/javascript">
   var WRInitTime=(new Date()).getTime();
   <!-- ClickTale end of Top part -->]]>
<script name="Bottom" DoNotReplaceCondition = "&lt;!-- ClickTale Bottom part --&gt;">
<!-- ClickTale Bottom part -->
<script type='text/javascript'>
// The ClickTale Balkan Tracking Code may be programmatically customized using hooks:
// function ClickTalePreRecordingHook() { /*place your customized code here*/ }
// For details about ClickTale hooks, please consult the Wiki page
var ClickTaleFetchFrom="http://%RootPath%/ClickTaleCache.ashx?t=%CacheToken%";
<!-- ClickTale end of Bottom part -->

PLEASE NOTE: This is how the code looks like in a text editor. In a browser, "&lt;" will be converted to "<" and "&gt;" will become ">"

PLEASE ALSO NOTE: This code sample relates to both HTTP and HTTPS page tracking. Your account may or may not have the option to record HTTPS pages. Please check and consult with your account manager, if you need assistance.

3.5  Save the ClickTaleScripts.xml file in the root of your web site.

PLEASE NOTE: You may put it in a different location, but then you will have to modify the path of the ScriptsFile parameter on the web.config file.

Step 4 - Configuring the module

Access your website's "web.config" file.
Copy the following code into the file, right after the <configuration> tag.
Notice that the ClickTale script will be added to all pages that are being served by this specific config file unless a "do not insert" condition is met. See the Q&A section if you need to exclude certain .aspx files from being processed.

	<section name="ClickTale.IntegrationModuleSettings" type="System.Configuration.SingleTagSectionHandler"/>
	DoNotProcessCookieValue ="0"
	AllowedAddresses ="*" />
  • The MaxCachedPages parameter depends on your server hardware capabilities and the maximum amount of memory you would like to allocate for caching. Change it according to your needs. Considering that an average page size of about 40KB, 100 cached pages can mean 4Mb of your servers' memory.
  • The AllowedAddresses parameter allows you to set the ClickTale bot's IP ranges to permit it to fetch the cached pages on your server. Available values are:

For older versions (below

For version and above

Explicit IP addresses

Should be set to,

Whitespace-separated list of the following types of tokens:

  • [ip] – existing
  • [ip]/[mask] – existing
  • [hostname] – new
  • [wildcard hostname] – new

Example: *
A match with any of the tokens will be considered passing the AllowedAddresses check.
default value: none

Step 5 - Enabling the module

Locate the <system.web> element in the web.config file on your web server and insert the following code:

	<add name="ClickTaleIntegrationModule" type="ClickTale.IntegrationModule.ClickTaleIntegrationModule, ClickTaleIntegrationModule" />

Note 1: Make sure you paste the code under the <system.web> section located in the root of the XML document and not in any of the nested <system.web> sections, if there are such.

Note 2: if you already have an <httpModules> section simply copy&paste the <add ...> tag into it.

This will activate the module. In case you wish to disable the module, it is enough to comment out this section.

Note 3: Please be sure to remove any tracking code added to your pages manually as it inhibits the module from injecting the tracking code found within the xml file on these pages.

Note 4: If you are using IIS 7 please also refer to the additional settings detailed in the IIS 7 and 7.5 Compatibility section.

Step 6 - Testing

For optimization purposes, the module will only inject the code for visitors that are classified as "to-record" (i.e. have WRUID cookie with a non-zero value) or for those who are not yet classified (i.e. have no WRUID cookie at all). Visitors who are classified as "not-to-record" will have no tracking code added to their HTML. As a result you might not see the tracking code in the source of the page, while testing. This doesn't mean that the module doesn't work. Your classification depends on your ClickTale recording ratio.
You can use a cookie editor to set the WRUID cookie to a numeric value different than 0.
Alternatively, you can clear cookies, and force a recording, using the following instructions: here Once classified as "to-record" you should see the tracking code in the source code of each page on your site and recording should take place (this is of course, provided that the relevant domain is checked for recording in the Manage Domains list). If you still don't see the code, please proceed to the next section.

Troubleshooting and debugging

The module includes several debugging tools: a debug page, a log and some configuration flags which control the debug levels.

The relevant configuration parameters for enabling the debugging feature for the module are:

  • LogFileNameMask - holds the path to the location where the log files are created. Normally in the form LogFileNameMask="~\ClickTaleLog{0}.txt" (where {0} is the current date). The log file has to be enabled for writing by IIS/ASP.
  • AllowDebug - enables access to the debug page which is located at ~/ClickTaleDebug.ashx. Set to "true" to enable this functionality.

Once this parameter is set to "true" you are able to access the page http://[YOUR DOMAIN]/ClickTaleDebug.ashx in order to view the details of the implementation as well as a snapshot of the latest log.

  • DebugCode - enables some extra logging of each read and write events in the module. Used to debug difficult cases. The log must also be enabled for this to work correctly. Set to "true" to enable this functionality.

All parameters above should be added to the web.config file - see step 4

If you don't see the tracking code in your pages, please enable the debug page and try to access it. If you are getting broken recordings, please see the next section for possible causes.

Load Balancing Scenario

By Default, the module uses the local server cache for storing the temporary cached pages. That content is later fetched by the ClickTale bot and saved on the ClickTale servers. When using a multi server environment and a load balancer to distribute the requests across the servers there is a chance that a visitor will be forwarded to a different server than the one to which the ClickTale Bot is forwarded. As a result the bot will hit a server that doesn't contain the requested information and the request for fetching the cached page (not the page presented to the visitor) will fail with a 404 error.

There are two manners to overcome this issue:

  • A way to force the request form the ClickTale to reach a specific server in the farm.
  • A Centralized cache location.

Forcing a specific server

Using direct host for fetching

If you have a dedicated host for each server in the farm, and you are able to access resources of the web site by going to a direct URL, then you can set ClickTale to fetch from a specific server. To do so you would customize the ClickTaleFetchFrom URL of each server to specify a direct URL to that server. For example if your site is and your servers are,, you would change the bottom tracking code on each server to have the ClickTaleFetchFrom URL refer to the specific server directly. Like so: For the first server:

ClickTaleFetchFrom="http://" + "";

For the second server:

ClickTaleFetchFrom="http://" + "";

and so on.

The added code should be placed according to your code type, as outlined in this Code Placement article.

Using cookies for accessing a specific server

Some load balancers use an HTTP cookie to assign a specific visitor to a specific server permanently. This is often called "Sticky Sessions". If you know that such a cookie exists in your environment, you should be able to have the Bot reach the original server by recording the cookie value. This is done using the FetchFromWithCookies API. To do so, change the ClickTaleFetchFrom line to:


Where [!COOKIENAME!] is the name of the cookie that maintains the visitor's affinity to a specific server.

The added code should be placed according to your code type, as outlined in this Code Placement article.

Centralized Caching Location - Caching Content To a Database

In some cases the local server cache may not be suitable for storing the cached pages (e.g. load balancing scenario) . For such cases the module has a feature that enables storing cached pages in a database. Please follow these steps if you choose to storing cached pages in a DB:

  1. Run a script called "ASP.NET Integration Module SQL Script.sql" available in the zip file downloaded. This will create the database, tables and other elements used.
  2. Add a new connection string that will connect to the new "ClickTale" database, name it "ClickTale" (please be sure to use this name).
  3. Add the ConnectionStringName="ClickTale" and MaxCachedSeconds="240" attributes to the ClickTale.IntegrationModuleSettings element in the web.config file. You may also remove MaxCachedPages, as it is not used by the DB cache.

MaxCachedSeconds represents the number of seconds a cached page will be stored in the database. Entries older than MaxCachedSeconds will be deleted when new entries are added. An example of a connection string and a configuration element may be seen here:

	<add name="ClickTale" connectionString="Data Source = .\SQLEXPRESS; Initial Catalog = ClickTale; User Id = User; Password = Pass; MultipleActiveResultSets = True" providerName="System.Data.SqlClient" />
	DoNotProcessCookieValue="0" />

Use With "Expires" Header And Enable Reuse Of Cached Pages (if you are getting 404 errors for some of the pages of some of the visitors)

Some websites use "cache-control" and "expires" headers to cache pages on the client. This improves performance but may be problematic when used with our module.

Pages are removed from the module's cache right after they are being fetched by the ClickTale bot(for security and performance reasons). Therefore, if a visitor browses a page more than once without refreshing the content from the server (usually a result of using the back button), ClickTaleCache.ashx will be called several times with the same token. This will cause a cache miss for any request other than the first one.

To overcome this problem, it is possible to use the DeleteAfterPull="false" parameter in the configuration. This will disable the removal of cached pages immediately after the ClickTaleCache.ashx is called. Cached data will be removed once the 'MaxCachedPages' limit is reached, so you may want to extend this parameter as well to allow sufficient traffic between the first pageview and the next (duplicate pageview).

Additionally, you can change your HTTP cache control to "no-cache" which might be more correct for your application logic.

Please note that "DeleteAfterPull" is not available when caching content to database storage. To achieve the same effect with a "database cache", please edit the "CachePullCachedPage" SP of the ClickTale cache database and change it to only perform: "SELECT Page FROM CachedPages WHERE Token = @Token" . Use the "MaxCachedSeconds" parameter instead of "MaxCachedPages" to control the period of time for which to keep the content in cache.

IIS 7 and 7.5 Compatibility

At times, additional steps for IIS 7/7.5 users are required for the correct operation of the module. If the ClickTale Integration Module does not work, please add the following line to your "web.config" file:

<add name="ClickTaleIntegrationModule" type="ClickTale.IntegrationModule.ClickTaleIntegrationModule" preCondition="managedHandler" />

This line should go inside

	<validation validateIntegratedModeConfiguration="false" />
		<!-- Goes Here -->

Using with a (reverse) proxy server

If you are using a (reverse) proxy server, that server could change the request in such a way that it appears to originate from the proxy and not from the ClickTale servers. This will prevent the module from authenticating the request based on the IP address. There are two ways to work around this issue:

  • Change the allowed addresses ("AllowedAddresses" parameter) value in the configuration section of ASP module in your web.config file and set it to the IP of the proxy. You will then need to configure your proxy to block access to the ClickTaleCache.ashx file and only grant access to IPs "" (note, this stands for - and - using CIDR notation)- The latter recommendation is to ensure that no requests other than that of the ClickTale Bot can access the cache location.


  • If your proxy includes the original IP address in the HTTP headers, you could add a module setting in your web.config file to instruct the module to use that header. If your proxy uses a header field called "X-Forwarded-For" (this is common), then add IPAddressHeaderFieldName="X-Forwarded-For" to your web.config file to utilize this field.

Please note that failing to implement the above security measures causes a potential security breach to your website. Please ensure that you have taken the necessary steps. Contact ClickTale support if you have any questions.

Conflicts with other modules

In some cases, conflicts can occur with other modules that you may have on your site. This is usually an issue to consider if you are using compression modules rather than the IIS built-in compression.
Conflicts can often be solved by making sure that the ClickTale module is installed on top of the filter chain, such that it can handle the content first. To achieve that try:

a) Adding the ClickTale Integration Module httpmodule entry as the last in the list of modules.

b) If 'a' doesn't resolve the issue, try adding the FilterInstallEvent="PostReleaseRequestState" parameter as one of the configuration attributes of the module( in the web.config file).

Conflicts with an installed CMS

In some cases a CMS used, will prevent access to the ClickTale "Virtual URLs" ClickTaleDebug.ashx and ClickTaleCache.ashx. For example, it might redirect them to a custom not-found page.

If you start browsing to ClickTaleCache.ashx or ClickTaleDebug.ashx and you get a CMS-generated error page, try creating a stand-alone handler in order to bypass the httpHandlers declaration defined in the Web.Configfile.

To create those handlers please follow these steps:

1. Create 2 new Generic handlers in your Visual Studio in the root folder of your website. In order for the URL of the handlers to correspond to http://[your domain]/ClickTaleCache.ashx), name them ClickTaleCache.ashx and ClickTaleDebug.ashx

2. Open ClickTaleDebug.ashx for edit in Visual Studio and paste the following code into the ProcessRequest method so it will look like this:

public void ProcessRequest(HttpContext context)
    ClickTaleIntegrationModule module = (ClickTaleIntegrationModule)context.ApplicationInstance.Modules["ClickTaleIntegrationModule"];

3. Open ClickTaleCache.ashx for edit in Visual Studio and paste the following code into the ProcessRequest method so it will look like this:

public void ProcessRequest(HttpContext context)
    ClickTaleIntegrationModule module = (ClickTaleIntegrationModule)context.ApplicationInstance.Modules["ClickTaleIntegrationModule"];

4. Compile your project.

This should manually run the handlers without relying on the httpModule which maybe not be working because of the CMS. This workaround has been tested with SiteCore CMS.

If none of those solutions work, please contact ClickTale Support.

Multiple domains (inc. TLD)

When migrating from a Staging environment into a Production one, the RootPath can bind to the first request loaded into the application cache (i.e. the first host requested) eg. there can be over a dozen TLDs (hosts) utilising the same application pool in larger sites:

In such cases the line:


can be edited to read:

ClickTaleFetchFrom="http://"+ document.domain +"/ClickTaleCache.ashx?t=%CacheToken%";

This should prevent the ClickTale bot querying the same domain for all cached items.

The added code should be placed according to your code type, as outlined in this Code Placement article.


I have already defined caching correctly on my server. I don't want to change the caching of my pages. Why do you add caching?

The module caches the content of the pages for its own use. This cache has no effect on the delivery of the pages to the visitors, nor does it change your existing server side or client side cache schemes. This is a separate cache designed to hold the content temporarily in memory until our servers request it from the module.

"Parser Error Message: Exception creating section handler" configuration error is displayed when trying to view pages on the website.

Open your web.config file and change the following line:

	<section name="ClickTale.IntegrationModuleSettings" type="System.Configuration.SingleTagSectionHandler" />

to read:

	<section name="ClickTale.IntegrationModuleSettings" type="System.Configuration.SingleTagSectionHandler, System, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

Are cached pages protected from access by third party elements?

Yes, several layers of protection are in place. Only certain IPs are allowed to request the cached pages (IPs of the ClickTale servers) and only processes which already have access to the page have the unique token required to request the cached content.

Is it possible to inject the script in other places rather than after/before body tags?

Yes. By default the top script is injected after <body> and the bottom before </body>, but this can be changed by adding an 'InsertAfter' attribute to the script[name="Top"] element or adding an 'InsertBefore' attribute to the script[name="Bottom"] element, both are regular expressions.

There is a specific page that I don't want recorded, but the module adds ClickTale script to every page.

The ASP.NET Integration module is a site wide module that will process all pageviews on your site and try to inject the configured ClickTale code into them. You will have to use one of the following solutions to ignore one or more pages (Please note that the first method suggested is dependent on the content of the page while the second method is dependent on the URL of the page):

  • You can configure the module to ignore some pages by using the DoNotReplaceCondition attribute on a script element in the ClickTaleScripts.xml file. This property is a regular expression. When there is a match for this expression with page content on the page near the InsertBefore/InsertAfter condition, the script will not be added. Make sure that all pages you want to exclude meet this condition. For example, you can add a note in an HTML comment before the </body> tag that will function as a "do not replace" condition.
What you will do is:
1. Modify your ClickTaleScripts.xml file to have the "DoNotReplaceCondition" property like this:
  <script name="Bottom" DoNotReplaceCondition="&lt;!-- No ClickTale --&gt;">
2. Modify the pages you want to exclude to have the condition right before the </body> tag like this:
      <!-- No ClickTale -->
When the module detects this text it will not inject the ClickTale code.
You can also use this mechanism for other strings and conditions you might find in your code. For example, if you only want to include the Clicktale code in pages containing a word or string, you can use the code below. For instance it is possible to only record users that are logged in by using a word like: "logout".
  • The latest versions of the module allow you to define WhitelistURLRegex and BlacklistURLRegex regular expression values in the configuration section. The regular expressions will be matched against the full URL of the page. If a white-list is present, then the tracking code will be injected only into URLs that match the white-list expression. If a black-list is present, then the tracking code will be injected only into URLs that don't match the black-list expression.

Let's say you want to whitelist two pages: page1.aspx and page2.aspx

Therefore, the following needs to be added to the Module's configuration file:


To disable code injection for an admin part of the site/CMS the following example can be used.

  • Another option, which is less recommended for ASP.NET, is to use the PHP control script. The PHP control script allows you to set a list of pages to record or ignore and will require you to customize your ClickTale tracking code a little.

Some of my pages already have the ClickTale script; I do not want the script to appear twice.

You should either remove the script from those pages and let the module handle the insertion or you should use the DoNotReplaceCondition. See the code step 2 for an example. The default script in Step 2 is already configured to prevent double inclusion.

After installing the module, I tried to watch a recording but I got the following notice instead: "Request from an unauthorized IP." What should I do?

This could be due to a misconfiguration, the use of a proxy, a change in our IP addresses or a hacking attempt. Please check your settings, specifically the "AllowedAddresses" parameter.

I have installed the module but I don't see the tracking code in the source of the page. What is wrong?

The module will only inject the code for visitors who are selected to be recorded (have the WRUID cookie with a value different from 0 ) or for those who are not classified (i.e. the visitors who do not yet have the WRUID cookie - meaning it has not been decided yet whether they would be recorded). Visitors who are classified as "not-to-be-recorded" will not be presented with the tracking code.

How can I disable the caching and leave only the script injection?

Do note that disabling caching defeats the main purpose of the module and correct page content might not be recorded. The best practice for this case is to put the static tracking code in the website's template. If you still want to use the module for code injection but not for content caching, you can add the parameter DisableCache="True" to the ClickTale.IntegrationModuleSettings element in the web.config file. When setting DisableCache to True, you need to remove the ClickTaleFetchFrom line from the ClickTaleScripts.xml file or else nothing will be fetched.

I'm getting an HTTP 500.22 error after deploying the ASP.NET IM on IIS 7 application pools in "Integrated" mode. How do I fix this?

In this case,you'll need to add the following tag to the web.config file under the <system.webServer> section:

<validation validateIntegratedModeConfiguration="false" />

I'm receiving "The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed..." on my site root page once the module is installed. Full URLs that include the file name produce correct behavior.

Please make sure that you are not using IIS6 with “Wildcard App Mappings” option enable in the IIS config of your site. Such a configuration is not supported by this module.

I'm receiving "Post cache substitution is not compatible with modules in the IIS integrated pipeline that modify the response buffers. Either a native module in the pipeline has modified an HTTP_DATA_CHUNK structure associated with a managed post cache substitution callback, or a managed filter has modified the response." on my site root page once the module is installed.

This happens because you are using post-cache substitution along with the ClickTale integration module which is a response filter and they are not compatible.
For more information please read
The ClickTale Integration module and Post-Cache Substitution cannot work together.

How is RootPath determined and how do I change it?

The host (which is used for RootPath) is registered once when the module is first loaded. It changes when you restart the web server or when you make a change in the ClickTaleScripts.xml file. To change it, please restart your web server, then access your site from a URL using the host you wish to serve as root path.