First off let me state that I wouldn't advise using Session variables in an ASP.NET web application for anything business related. Session is helpful for storing a user's breadcrumb trail or other minor settings. As a simple rule, if a user of your web application loses his or her session, it should only be a minor setback, and should not be a devastating problem that causes data loss or other major issues. For example, if a session is lost, the user's breadcrumb trail should just be rebuilt (if possible), or just put back to a state that may not be as helpful as before, but is still somewhat helpful. As another example, the user might simply lose his or her last search settings. At any rate, it should definitely never cause an error or exception to occur.
I spent many hours combing through solutions to this problem on the web. Eventually I put together some code that worked well for ASP.NET web forms. When we moved our projects to ASP.NET MVC 1.0, it was only natural to come up with a way that fit into the MVC framework. This is that solution.
I've designed this solution so that it could be placed in a separately maintained library and used by any of your projects. That said, I've named my code library "MyLibrary". As a standard way of preventing name clashes, I've also prefixed every class and file in this solution with "MyLibrary". Here is a screenshot of the Solution Explorer (Visual Studio 2008 / C#)...the actual code will follow later in this article:
How to use in your project
Download the MyLibrary solution.
After you create and build "MyLibrary", you just need to add a reference to MyLibrary.Web.dll in your project, and call the HtmlHelper. I typically put it in my master files as follows. The key lines are 3 and 8:
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<%@ Import Namespace="MyLibrary.Web.Mvc" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<%= Html.KeepSessionAlive(Context) %>
This will make the view refresh itself 10 seconds before the session times out.
public class MyLibraryMvcKeepSessionAliveController : Controller
public ActionResult Index()
Response.AddHeader("Refresh", Convert.ToString(((Session.Timeout * 60) - 10)));
This is the actual view that will refresh to keep the session alive. The user will not see this on their page, because it will be in an iframe with a border, width, and height of zero.
NOTE: This view's "Build Action" property should be set to "Embedded Resource".
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<!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 id="Head1" runat="server">
<title>Keep Session Alive</title>
<meta http-equiv="expires" content="Sun, Dec 31 1970 12:00:00 GMT" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="pragma" content="no-cache" />
<form id="form1" runat="server"></form>
public static class MyLibraryMvcExtensions
/// Simplifies the process of returning a view that is marked as an embedded resource.
public static ViewResult PluginView(this Controller controller)
string controllerName = controller.RouteData.GetRequiredString("controller");
string viewName = controller.RouteData.GetRequiredString("action");
string assemblyName = controller.GetType().Assembly.FullName.Split(',');
string pluginPath = string.Format(
assemblyName, controllerName, viewName
ViewName = pluginPath,
ViewData = controller.ViewData,
TempData = controller.TempData,
This is the HtmlHelper that can be used on any view in your project. I prefer to use it on the Site.master page so I don't have to have it on every page.
public static class MyLibraryMvcHtmlHelpers
public static string KeepSessionAlive(this HtmlHelper helper, HttpContext context)
UrlHelper urlHelper = new
string url = urlHelper.Action("Index", "MyLibraryMvcKeepSessionAlive");
return "<iframe id=\"KeepSessionAlive\" src=\"" + url + "\" frameborder=\"0\" width=\"0\" height=\"0\" runat=\"server\"></iframe>";
Other settings required for this to work
Make sure your application is running in its own IIS application pool. By default, an IIS application pool will occasionally recycle itself...which kills all active sessions. You will need to disable all recycling. You can change the session timeout to a small number...i.e., 5 minutes. As long as we have the keep session alive code refreshing the session just before it expires, you can use a small session timeout. This will ensure that you do not have a build up of sessions hanging around, and will allow your application pool to shut down more often due to inactivity, thus keeping it healthy.