I ended up understanding that a postback is not much suitable for background activities not related to page rendering. A cleaner approach would be calling a WebService or posting to a different page. Extending the Timer
class, I was able to achieve the second strategy overriding the javascript function called when the timer ticks, making it able to perform a Post to a different url. Feel free to point me to other ajax controls that behaves similarly.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.ComponentModel;
using System.Text;
namespace AjaxExt
{
[ToolboxData("<{0}:TimerEx runat=server></{0}:TimerEx>")]
public class TimerEx : Timer
{
public const string POST_FIELD = "__TIMEREXDATA";
public TimerEx()
{
TimerMode = TimerMode.DoPostBack;
PostUrl = "";
PostData = "";
PostField = "";
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (TimerMode.HasFlag(TimerMode.DoPost) && !String.IsNullOrEmpty(PostUrl))
{
string postUrl = PostUrl.StartsWith("/") ? PostUrl : "/" + PostUrl;
string postField = String.IsNullOrEmpty(PostField) ? POST_FIELD : PostField;
// Override tick function
StringBuilder builder = new StringBuilder();
builder.AppendLine("function pageLoad() {");
builder.AppendLine(" var timer = $find('" + this.ClientID + "');");
builder.AppendLine(" timer._doPostback = function () {");
builder.AppendLine(" $.ajax({");
builder.AppendLine(" url: \"" + postUrl + "\",");
if (String.IsNullOrEmpty(PostData))
builder.AppendLine(" data: null,");
else
builder.AppendLine(" data: { " + postField + ": " + PostData + "},");
builder.AppendLine(" success: null,");
builder.AppendLine(" error: null");
builder.AppendLine(" });");
if (TimerMode.HasFlag(TimerMode.DoPostBack))
builder.AppendLine(" __doPostBack(this.get_uniqueID(),'');");
builder.AppendLine(" };");
builder.AppendLine("}");
Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "dopostscript", builder.ToString(), true);
}
}
[DefaultValue(TimerMode.DoPostBack)]
public TimerMode TimerMode
{
get;
set;
}
[DefaultValue("")]
public string PostUrl
{
get;
set;
}
[DefaultValue("")]
public string PostData
{
get;
set;
}
[DefaultValue("")]
public string PostField
{
get;
set;
}
}
[Flags]
public enum TimerMode
{
DoPost = 1,
DoPostBack = 2,
DoBoth = DoPost | DoPostBack
}
}
It can be added to a page as it follow:
<%@ Register Assembly="AjaxExt" Namespace="AjaxExt" TagPrefix="jaxext" %>
<ajaxext:TimerEx ID="PingTimer" runat="server" PostUrl="HeartBeat.aspx"
TimerMode="DoPost" Interval="10000" />