Get an unique session in each browser tab

I got a lot to do at work, hence the silence. I got a lot to blog about, but so little time ;/ I found an interesting question at stackoverflow which this answer is for (also to show you that the blog is not forgotten).

A user wanted to store browser tab specific data which can be a problem since most browsers shares a session between different tabs. The solution is to create a new route which generates a GUID and then
use that guid to fetch and store session information. Keep in mind that you need to routes: One that works for users which just surfed into the site, and one that loads an existing guid.

Here is the route class:

public class GuidRoute : Route
{
	private readonly bool _isGuidRoute;

	public GuidRoute(string uri, object defaults)
		: base(uri, new RouteValueDictionary(defaults), new MvcRouteHandler())
	{
		_isGuidRoute = uri.Contains("guid");

		DataTokens = new RouteValueDictionary();
	}

	public override RouteData GetRouteData(HttpContextBase httpContext)
	{
		var routeData = base.GetRouteData(httpContext);
		if (routeData == null)
			return null;

		if (!routeData.Values.ContainsKey("guid") || routeData.Values["guid"].ToString() == "")
			routeData.Values["guid"] = Guid.NewGuid().ToString("N");

		return routeData;
	}

	public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
	{
		return !_isGuidRoute ? null : base.GetVirtualPath(requestContext, values);
	}
}

Replace the default route in global.asax with it:

/*routes.MapRoute(
	"Default", // Route name
	"{controller}/{action}/{id}", // URL with parameters
	new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);*/

routes.Add("Default", new GuidRoute(
	"{controller}/{action}/{id}", 
	new { controller = "Home", action = "Index", guid = "", id = UrlParameter.Optional }));

routes.Add("GuidRoute", new GuidRoute(
	"g/{guid}/{controller}/{action}/{id}", 
	new { controller = "Home", action = "Index", guid = "", id = UrlParameter.Optional }));

And finally some extension methods to make life easier in the controllers:

public static class ControllerExtensionMethods
{
	public static string GetGuid(this Controller controller)
	{
		return controller.RouteData.Values["guid"].ToString();
	}

	public static void SetGuidSession(this Controller controller, string name, object value)
	{
		controller.Session[controller.GetGuid() + "_" + name] = value;
	}

	public static object GetGuidSession(this Controller controller, string name)
	{
		return controller.Session[controller.GetGuid() + "_" + name];
	}
}

One thing left though: Any browser bookmarks will use an old GUID. Should not be a problem in most cases (unless the user opens the bookmark in multiple tabs = sharing the session between the tabs). Same
thing goes for opening a link in a new tab = shared.