What is the best approach to handle session timeouts in asp.net
There are various ways to handle session timeouts, like "meta refreshes" javascript on load functions etc.
I would like something neat like: 5 minutes before timeout, warn the user...
I am also contemplating keeping the session open for as long as the browser is open(still need to figure out how to do it though... probably some iframe with refreshing).
How do you handle session timeouts, and what direction do you think i should go in?
Solution 1:
The best approach to handle sessions timeouts.
I say that there is 2 basic cases.
One is when the users enter little or no data, and just read reports, or do small thinks with his mouse. In this case there is not easy way to inform him that the session is going to expire. If you going to check the time left for the session calling the code behind, then automatically you update the session. Then if you have a timer to count down the session, then maybe the user have open a new tab of your web and the session is going to expired but not the time you have note with javascript and the user receive wrong message.
So for me, when the user enter little or no data, just let the session expired, if he lose one click, it will do it again later.
Second is when the user need to enter many data, that some time can take time, a long text for example, to write it and fix it. In this case I use the below technique and I am not let the session go out.
How to keep the session open as long as the browser.
Here is a very nice and simple technique, I use an image that I make an reload of it before the session is timeout using JavaScript.
<img id="keepAliveIMG" width="1" height="1" src="/img/ui/spacer.gif?" />
<script language="javascript" type="text/javascript">
var myImg = document.getElementById("keepAliveIMG");
if (myImg){
window.setInterval(function(){
myImg.src = myImg.src.replace(/\?.*$/, '?' + Math.random());
}, 6000);
}
</script>
In a third case, you can do this. We care if the session is expired only on post back. When the user have enter some data and on the post back the application is redirect him on the login page and the post lost.
In this third case you can capture the post data and saved them until the user re-login. You capture the post data on global.asax
on the
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
This is the function that called before the redirect to the login page, and there you see if you have post data and the use required to login, you save that post data, ether to a new redirect page, ether to the server (maybe on session, maybe on your temporary database).
Now after the user is login again, you redirect him again to the last page with the saved post data, and the user is continue as it is.
The only trick here is to make a middle page, that render the form with the last posted data and an automatically redirect javascript call.
Solution 2:
The only thing I can think of is to generate some script on the page that creates a client timer, so that when the page is received and rendered, it can show an alert X-minutes later (that is 5mins before expire).
If you'd rather have the session just keep itself alive, you can do this with a generic handler (ASHX) that you periodically call via AJAX. This will help refresh the session and it should stay alive for as long as the AJAX calls continue.
Example "keepalive.ASHX":
<%@ WebHandler Language="C#" Class="keepalive" %>
using System;
public class keepalive : System.Web.IHttpHandler
{
public void ProcessRequest (System.Web.HttpContext context)
{
context.Response.ContentType = "text/json";
var thisUser = System.Web.Security.Membership.GetUser();
if (thisUser != null)
context.Response.Write("[{\"User\": \"" + thisUser.UserName + "\"}]");
}
public bool IsReusable
{
get { return false; }
}
}
And here's the script on the page to call it (with jQuery for simplicity):
<script type='text/javascript'>
function keepAliveInterval()
{
$.ajax(
{
url: "keepalive.ashx",
context: document.body,
error: function () {
alert("AJAX keepalive.ashx error :(");
}
});
}
$(document).ready(function () {
window.setInterval('keepAliveInterval()', 60000);
});
</script>