ASP.NET MVC中多个浏览器选项卡中的唯一会话

时间:2014-04-02 15:44:48

标签: asp.net asp.net-mvc

每当用户在ASP.NET MVC应用程序中打开新的浏览器选项卡或窗口时,我想创建唯一的会话。是否可以在ASP.NET / MVC中使用?

我尝试按照以下解决方案

asp.net - session - multiple browser tabs - different sessions?

但是它在ASP.NET MVC中不起作用。上面的解决方案使用ViewState,在MVC中我尝试使用TempData,但它不起作用。

3 个答案:

答案 0 :(得分:6)

多年后我终于找到了解决这个问题的方法:

1。)浏览器必须自己提供ID,因为http是无状态的,cookie不是单独存储在浏览器选项卡中,因此asp.net会话也不区分单个选项卡。

2。)打开新标签时,JS window.name为''。将window.name更改为某个值后,只要该选项卡处于活动状态并且某些代码未更改它,它就不会再更改。

所以解决方案是:在* .master或每个* .aspx文件中实现一些简短的JS代码:

 if (typeof window.name != undefined) {
             if (window.name == '') {
                 var d = new Date();
                 window.name = '_myWnd_' + d.getUTCHours() + d.getUTCMinutes() + d.getUTCSeconds() + d.getUTCMilliseconds();
             }
             var eDiv = document.getElementById('div_BrowserWindowName');
             var e = eDiv.getElementsByTagName('input')[0];
             e.value = window.name;
         }

还要添加* .master或每个* .aspx文件的表单部分:

 <div id="div_BrowserWindowName" style="visibility:hidden;">
                <asp:HiddenField ID="hf_BrowserWindowName" runat="server" />
            </div>

现在,您可以通过在每次回发后读取隐藏字段来检索window.name == UNIQUE ID,即使用户从一个站点跳到另一个站点并在几个小时后返回到表单。

答案 1 :(得分:1)

如您所知,HTTP是无状态的,并且在请求之间具有状态的一种非常常见的机制是使用会话变量。当您打开一个新的浏览器选项卡时会出现问题,因为会话是相同的,因此您在新选项卡中所做的任何更改都会影响其他选项卡。 您没有确切地指定您想要做什么,但是假设您有一个产品列表页面,用户可以在其中输入搜索过滤器并且您希望将它们保存在会话中。如果用户在选项卡1中设置了搜索过滤器值,则选项卡2将具有相同的值(它们共享会话变量)。你能做什么?

1)使用此方法在URL中添加guid:http://www.codeproject.com/Articles/331609/Get-an-unique-session-in-each-browser-tab

2)做一些类似于前面所描述的内容但不是以同样的方式,这就是我为解决同样的问题所做的。

a)我对serach页面的链接是/ Product / List?guid = xxx而不是/ Product / List。如果用户手动输入/ Product / List,我会将他重定向到设置了GUID的新URL。

public ActionResult List(string guid)
        {
            if (guid == null)
            {
                return RedirectToAction("List", new { guid = Guid.NewGuid().ToString() });
            }
...

每次点击“列表”链接并定位新标签时,都会生成新的GUID。

b)我有一个带GUID的会话密钥,因此每个页面都有自己的值。你可以同时打开2个标签,它们会使用不同的会话值,因为guid会有所不同。

这个解决方案并不完美但至少可行。

我希望它有所帮助。

答案 2 :(得分:0)

第一个答案的变体,HTML 5,是使用window.sessionStorage而不是设置window.name。所以你可以在你的应用程序的入口页面上做这样的事情:

var uniqueId = "<%= Guid.NewGuid().ToString() %>";
window.sessionStorage.setItem("tabId", uniqueId);

然后在每个需要会话的控制器操作中,您将参数传递给:

window.sessionStorage.getItem("tabId");