AJAX & Session State

I’ve been researching a way to keep my user Sessions alive, even between callbacks, as my application relies heavily on AJAX. Most articles online say that your Session timer will not be reset following each AJAX request, only on postbacks.

To test this I wrote a page which has 2 buttons: 1 for postback and 1 for callback. If I issue a callback I update a counter stored in a Session variable and then load that counter into a Label. I set my Session timeout to 2 minutes int he web.config. What I do is load the page, click on the Callback button every few seconds and see if a breakpoint is triggered in my Session_End event.

When running the sample app I’m seeing unpredictable results. Sometimes the session never seems to expire as long as I continue to click on the Callback button. Sometimes my Session will expire at the 2 minute mark and the Session_End event will be called, but when my code returns to the page the Session variable has not been cleared?? The more I test it seems the more lost I get…

Here is my test page:


<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
  <title>AJAX Timer Test</title>
</head>
<body>
<form id="form1" runat="server">

<asp:ScriptManager runat="server" ID="ScriptManager1" EnablePartialRendering="true">
</asp:ScriptManager>

<asp:UpdatePanel runat="server" ID="IndependentPanel">
  <ContentTemplate>
    Current Time: <asp:Label runat="server" ID="labCurrentTime" />
    <br />
    Counter: <asp:Label runat="server" ID="labCounter" />
    <br />
    Timeout: <asp:Label runat="server" ID="labSessionTimeout" />
    <br />
    <asp:Button runat="server" ID="butGetTime" Text="Ajax Request" onclick="butGetTime_Click"/>
  </ContentTemplate>
</asp:UpdatePanel>

<br />
<asp:Button runat="server" ID="butPostback" Text="Postback" />

</form>
</body>
</html>

…and the code-behind:


using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;

public partial class _Default : System.Web.UI.Page 
{
    protected void Page_Load(object sender, EventArgs e)
    {
      labCurrentTime.Text = DateTime.Now.ToLongTimeString();
      if (!IsPostBack)
      {
        Session["Counter"] = 1; 
      }
    }

    protected void butGetTime_Click(object sender, EventArgs e)
    {
      labCurrentTime.Text = DateTime.Now.ToLongTimeString();
      Session["Counter"] = int.Parse(Session["Counter"].ToString()) + 1;
      int j = 0;
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
      labCounter.Text = Session["Counter"].ToString();
      labSessionTimeout.Text = Session.Timeout.ToString();
    }
}

I’ve implemented a few keep alive systems. AJAX works just fine, biggest pitfall is browser caching–need a random number on the request side, and the response needs to have content. But it definitely works.