[c#] Keeping ASP.NET Session Open / Alive

Which is the easiest and most unobstrusive way to keep an ASP.NET session alive as long as the user has the browser window open? Is it timed AJAX calls? I want to prevent the following: sometimes users keep their window open for a long time, then enter stuff, and on submit nothing works anymore because the server side session expired. I don't want to increase the timeout value for more than 10 min on the server as I want closed sessions (by closing the browser window) to time out fast.

Suggestions, code samples?

This question is related to c# asp.net session

The answer is


you can just write this code in you java script file thats it.

$(document).ready(function () {
        var delay = (20-1)*60*1000;
        window.setInterval(function () {
            var url = 'put the url of some Dummy page';
            $.get(url);                
        }, delay);
});

The (20-1)*60*1000 is refresh time, it will refresh the session timeout. Refresh timeout is calculated as default time out of iis = 20 minutes, means 20 × 60000 = 1200000 milliseconds - 60000 millisecond (One minutes before session expires ) is 1140000.


Here JQuery plugin version of Maryan solution with handle optimization. Only with JQuery 1.7+!

(function ($) {
    $.fn.heartbeat = function (options) {
        var settings = $.extend({
            // These are the defaults.
            events: 'mousemove keydown'
            , url: '/Home/KeepSessionAlive'
            , every: 5*60*1000
        }, options);

        var keepSessionAlive = false
         , $container = $(this)
         , handler = function () {
             keepSessionAlive = true;
             $container.off(settings.events, handler)
         }, reset = function () {
             keepSessionAlive = false;
             $container.on(settings.events, handler);
             setTimeout(sessionAlive, settings.every);
         }, sessionAlive = function () {
             keepSessionAlive && $.ajax({
                 type: "POST"
                 , url: settings.url
                 ,success: reset
                });
         };
        reset();

        return this;
    }
})(jQuery)

and how it does import in your *.cshtml

$('body').heartbeat(); // Simple
$('body').heartbeat({url:'@Url.Action("Home", "heartbeat")'}); // different url
$('body').heartbeat({every:6*60*1000}); // different timeout

Whenever you make a request to the server the session timeout resets. So you can just make an ajax call to an empty HTTP handler on the server, but make sure the handler's cache is disabled, otherwise the browser will cache your handler and won't make a new request.

KeepSessionAlive.ashx.cs

public class KeepSessionAlive : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
            context.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1));
            context.Response.Cache.SetNoStore();
            context.Response.Cache.SetNoServerCaching();
        }
    }

.JS:

window.onload = function () {
        setInterval("KeepSessionAlive()", 60000)
}

 function KeepSessionAlive() {
 url = "/KeepSessionAlive.ashx?";
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", url, true);
        xmlHttp.send();
        }

@veggerby - There is no need for the overhead of storing variables in the session. Just preforming a request to the server is enough.


In regards to veggerby's solution, if you are trying to implement it on a VB app, be careful trying to run the supplied code through a translator. The following will work:

Imports System.Web
Imports System.Web.Services
Imports System.Web.SessionState

Public Class SessionHeartbeatHttpHandler
    Implements IHttpHandler
    Implements IRequiresSessionState

    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

    Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        context.Session("Heartbeat") = DateTime.Now
    End Sub
End Class

Also, instead of calling like heartbeat() function like:

 setTimeout("heartbeat()", 300000);

Instead, call it like:

 setInterval(function () { heartbeat(); }, 300000);

Number one, setTimeout only fires once whereas setInterval will fire repeatedly. Number two, calling heartbeat() like a string didn't work for me, whereas calling it like an actual function did.

And I can absolutely 100% confirm that this solution will overcome GoDaddy's ridiculous decision to force a 5 minute apppool session in Plesk!


Here is a alternative solution that should survive if the client pc goes into sleep mode.

If you have a huge amount of logged in users then use this cautiously as this could eat a lot of server memory.

After you login (i do this in the LoggedIn event of the login control)

Dim loggedOutAfterInactivity As Integer = 999 'Minutes

'Keep the session alive as long as the authentication cookie.
Session.Timeout = loggedOutAfterInactivity

'Get the authenticationTicket, decrypt and change timeout and create a new one.
Dim formsAuthenticationTicketCookie As HttpCookie = _
        Response.Cookies(FormsAuthentication.FormsCookieName)

Dim ticket As FormsAuthenticationTicket = _
        FormsAuthentication.Decrypt(formsAuthenticationTicketCookie.Value)
Dim newTicket As New FormsAuthenticationTicket(
        ticket.Version, ticket.Name, ticket.IssueDate, 
        ticket.IssueDate.AddMinutes(loggedOutAfterInactivity), 
        ticket.IsPersistent, ticket.UserData)
formsAuthenticationTicketCookie.Value = FormsAuthentication.Encrypt(newTicket)

If you are using ASP.NET MVC – you do not need an additional HTTP handler and some modifications of the web.config file. All you need – just to add some simple action in a Home/Common controller:

[HttpPost]
public JsonResult KeepSessionAlive() {
    return new JsonResult {Data = "Success"};
}

, write a piece of JavaScript code like this one (I have put it in one of site’s JavaScript file):

var keepSessionAlive = false;
var keepSessionAliveUrl = null;

function SetupSessionUpdater(actionUrl) {
    keepSessionAliveUrl = actionUrl;
    var container = $("#body");
    container.mousemove(function () { keepSessionAlive = true; });
    container.keydown(function () { keepSessionAlive = true; });
    CheckToKeepSessionAlive();
}

function CheckToKeepSessionAlive() {
    setTimeout("KeepSessionAlive()", 5*60*1000);
}

function KeepSessionAlive() {
    if (keepSessionAlive && keepSessionAliveUrl != null) {
        $.ajax({
            type: "POST",
            url: keepSessionAliveUrl,
            success: function () { keepSessionAlive = false; }
        });
    }
    CheckToKeepSessionAlive();
}

, and initialize this functionality by calling a JavaScript function:

SetupSessionUpdater('/Home/KeepSessionAlive');

Please note! I have implemented this functionality only for authorized users (there is no reason to keep session state for guests in most cases) and decision to keep session state active is not only based on – is browser open or not, but authorized user must do some activity on the site (move a mouse or type some key).


Do you really need to keep the session (do you have data in it?) or is it enough to fake this by reinstantiating the session when a request comes in? If the first, use the method above. If the second, try something like using the Session_End event handler.

If you have Forms Authentication, then you get something in the Global.asax.cs like

FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(formsCookie.Value);
if (ticket.Expired)
{
    Request.Cookies.Remove(FormsAuthentication.FormsCookieName);
    FormsAuthentication.SignOut();
    ...             
     }
else
{   ...
    // renew ticket if old
    ticket = FormsAuthentication.RenewTicketIfOld(ticket);
    ...
     }

And you set the ticket lifetime much longer than the session lifetime. If you're not authenticating, or using a different authentication method, there are similar tricks. Microsoft TFS web interface and SharePoint seem to use these - the give away is that if you click a link on a stale page, you get authentication prompts in the popup window, but if you just use a command, it works.


I spent a few days trying to figure out how to prolong a users session in WebForms via a popup dialog giving the user the option to renew the session or to allow it to expire. The #1 thing that you need to know is that you don't need any of this fancy 'HttpContext' stuff going on in some of the other answers. All you need is jQuery's $.post(); method. For example, while debugging I used:

$.post("http://localhost:5562/Members/Location/Default.aspx");

and on your live site you would use something like:

$.post("http://mysite/Members/Location/Default.aspx");

It's as easy as that. Furthermore, if you'd like to prompt the user with the option to renew their session do something similar to the following:

    <script type="text/javascript">
    $(function () { 
        var t = 9;
        var prolongBool = false;
        var originURL = document.location.origin;
        var expireTime = <%= FormsAuthentication.Timeout.TotalMinutes %>;

        // Dialog Counter
        var dialogCounter = function() {
            setTimeout( function() {
                $('#tickVar').text(t);
                    t--;
                    if(t <= 0 && prolongBool == false) {
                        var originURL = document.location.origin;
                        window.location.replace(originURL + "/timeout.aspx");
                        return;
                    }
                    else if(t <= 0) {
                        return;
                    }
                    dialogCounter();
            }, 1000);
        }

        var refreshDialogTimer = function() {
            setTimeout(function() { 
                $('#timeoutDialog').dialog('open');
            }, (expireTime * 1000 * 60 - (10 * 1000)) );
        };

        refreshDialogTimer();

        $('#timeoutDialog').dialog({
            title: "Session Expiring!",
            autoOpen: false,
            height: 170,
            width: 350,
            modal: true,
            buttons: {
                'Yes': function () {
                    prolongBool = true;
                    $.post("http://localhost:5562/Members/Location/Default.aspx"); 
                    refreshDialogTimer();
                    $(this).dialog("close");
                },
                Cancel: function () {
                    var originURL = document.location.origin;
                    window.location.replace(originURL + "/timeout.aspx");
                }
            },
            open: function() {
                prolongBool = false;
                $('#tickVar').text(10);
                t = 9;
                dialogCounter();
            }
        }); // end timeoutDialog
    }); //End page load
</script>

Don't forget to add the Dialog to your html:

        <div id="timeoutDialog" class='modal'>
            <form>
                <fieldset>
                    <label for="timeoutDialog">Your session will expire in</label>
                    <label for="timeoutDialog" id="tickVar">10</label>
                    <label for="timeoutDialog">seconds, would you like to renew your session?</label>
                </fieldset>
            </form>
        </div>

[Late to the party...]

Another way to do this without the overhead of an Ajax call or WebService handler is to load a special ASPX page after a given amount of time (i.e., prior to the session state time-out, which is typically 20 minutes):

// Client-side JavaScript
function pingServer() {
    // Force the loading of a keep-alive ASPX page
    var img = new Image(1, 1);
    img.src = '/KeepAlive.aspx';
}

The KeepAlive.aspx page is simply an empty page which does nothing but touch/refresh the Session state:

// KeepAlive.aspx.cs
public partial class KeepSessionAlive: System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Refresh the current user session
        Session["refreshTime"] = DateTime.UtcNow;
    }
}

This works by creating an img (image) element and forcing the browser to load its contents from the KeepAlive.aspx page. Loading that page causes the server to touch (update) the Session object, extending the session's expiration sliding time window (typically by another 20 minutes). The actual web page contents are discarded by the browser.

An alternative, and perhaps cleaner, way to do this is to create a new iframe element and load the KeepAlive.aspx page into it. The iframe element is hidden, such as by making it a child element of a hidden div element somewhere on the page.

Activity on the page itself can be detected by intercepting mouse and keyboard actions for the entire page body:

// Called when activity is detected
function activityDetected(evt) {
    ...
}

// Watch for mouse or keyboard activity
function watchForActivity() {
    var opts = { passive: true };
    document.body.addEventListener('mousemove', activityDetected, opts);
    document.body.addEventListener('keydown', activityDetected, opts);
}

I cannot take credit for this idea; see: https://www.codeproject.com/Articles/227382/Alert-Session-Time-out-in-ASP-Net.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to asp.net

RegisterStartupScript from code behind not working when Update Panel is used You must add a reference to assembly 'netstandard, Version=2.0.0.0 No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization How to use log4net in Asp.net core 2.0 Visual Studio 2017 error: Unable to start program, An operation is not legal in the current state How to create roles in ASP.NET Core and assign them to users? How to handle Uncaught (in promise) DOMException: The play() request was interrupted by a call to pause() ASP.NET Core Web API Authentication Could not load file or assembly 'CrystalDecisions.ReportAppServer.CommLayer, Version=13.0.2000.0 WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for jquery

Examples related to session

What is the best way to manage a user's session in React? Spring Boot Java Config Set Session Timeout PHP Unset Session Variable How to kill all active and inactive oracle sessions for user Difference between request.getSession() and request.getSession(true) PHP - Session destroy after closing browser Get Current Session Value in JavaScript? Invalidating JSON Web Tokens How to fix org.hibernate.LazyInitializationException - could not initialize proxy - no Session How can I get session id in php and show it?