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.

  • 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?

      • shiv

        yes

  • 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..

    • 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?

        • shiv

          hey i want your help

      • 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?

      • 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.

      • shiv

        hello sir i’m getting error on “g/{guid}/{controller}/{action}/{id}”,
        error:
        Server Error in ‘/’ Application.
        The resource cannot be found.
        Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

        Requested URL: /g/9b80fa7f5a2d429d848979afd57b21e0

        • shiv

          how i can solve this

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

  • prasad

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

  • Praveen Mishra

    Could you please Guide me where and how to use ControllerExtensionMethods in controller or some where else Thanks& Regards
    Praveen Mishra

  • shiv

    hello sir i’m getting error on “g/{guid}/{controller}/{action}/{id}”,
    error:
    Server Error in ‘/’ Application.
    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

    Requested URL: /g/9b80fa7f5a2d429d848979afd57b21e0

  • shiv

    hello sir i’m getting error on “g/{guid}/{controller}/{action}/{id}”,
    error:
    Server Error in ‘/’ Application.
    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

    Requested URL: /g/9b80fa7f5a2d429d848979afd57b21e0

  • shiv

    i’m getting error on “g/{guid}/{controller}/{action}/{id}”,
    error:
    Server Error in ‘/’ Application.
    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

    Requested URL: /g/9b80fa7f5a2d429d848979afd57b21e0

  • shiv

    hello sir i’m getting error on “g/{guid}/{controller}/{action}/{id}”,
    error:
    Server Error in ‘/’ Application.
    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

    Requested URL: /g/9b80fa7f5a2d429d848979afd57b21e0

  • shiv

    hello sir i’m getting error on “g/{guid}/{controller}/{action}/{id}”,
    error:
    Server Error in ‘/’ Application.
    The resource cannot be found.
    Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

    Requested URL: /g/9b80fa7f5a2d429d848979afd57b21e0