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.


  • dmicic

    I’ve created a nuget package which simplifies session handling in tabbed browsing scenarios. http://blog.micic.ch/net/asp-net-mvc-conversational-session Maybe you will find it useful.

    • http://blog.gauffin.org/ jgauffin

      Nice.

  • Anjan

    Nice Article. Is there any way to avoid appending GUID in URL and managing from route data during the postbacks.

  • Mohamed Asane

    Could you please guid me, How I can use with mvc area registration?

    context.MapRoute(

    “Test_default”,

    “Test/{controller}/{action}/{id}”,

    new { action = “Index”, id = UrlParameter.Optional }

    );

    • VP

      Did you get an answer for this? I am trying to solve the same issue, pl let me know if you were able to do this with RegisterArea?

  • Chuck Bryan

    Nice article. Everything worked fine until I went back to Home/Index. I ended up swapping the routes registration and it worked!

  • csteinmueller

    Thank you for this nice solution. Helped me a lot in a earlier project. But now it has to be extended and handle a HttpGet parameter. But the parameter doesn’t get into my MVC action. Here’s already a stackoverflow question I asked yesterday. Can you help out? http://stackoverflow.com/questions/20517293/querystring-of-httpget-are-gone-in-multisession-mvc4-application

  • Moeg

    Hi, is there a sample solution which implements this? I can’t seem to get it to work – although my routeData gets populate with a GUID my URL doesn’t, i.e. my URL is always http://localhost:51179/ or http://localhost:51179/Home/Index. I was expecting to have the GUID appended to the URL? A working solution would be great to be able to go through. Here’s hoping..

    • http://blog.gauffin.org/ jgauffin

      Did you register the custom route first before the default one?

      • Moeg

        I got it working thanks. Is there a way to access the Guid stored in the RouteData from within another project, say, for example, a WCF service layer?

        • horii horii

          Hi there can you please explain to me how you got it work?

      • Moeg

        Is the best way to get the GUID from a separate project (e.g. class library) to just retrieve it from the query string?

      • http://mzangweicttraining.azurewebsites.com/ Siyabulela Mooi

        This is what I have done in my application:

        RouteConfig.RegisterRoutes(RouteTable.Routes); in the “Application_Start() of the Global.asax file.

        public static void RegisterRoutes(RouteCollection routes)

        {

        //routes.IgnoreRoute(“{resource}.axd/{*pathInfo}”);

        //routes.MapRoute(

        // name: “Default”,

        // url: “{controller}/{action}/{id}”,

        // defaults: new { controller = “DeviceManager”, action = “DeviceDetails”, id = UrlParameter.Optional }

        //);

        routes.Add(“Default”, new GuidRoute(

        “{controller}/{action}/{id}”,

        new { controller = “DeviceManager”, action = “DeviceDetails”, guid = “”, id = UrlParameter.Optional }));

        routes.Add(“GuidRoute”, new GuidRoute(

        “g/{guid}/{controller}/{action}/{id}”,

        new { controller = “Home”, action = “Index”, guid = “”, id = UrlParameter.Optional }));

        }

        This still doesn’t append the Giuid in the URL.

  • http://mzangweicttraining.azurewebsites.com/ Siyabulela Mooi

    When or where do the “ControllerExtensionMethods” methods get called?

  • prasad

    please any one guide me how to use above solution in mvc?