ASP.NET - 会话 - 多个浏览器标签页 - 不同的会话?

31

我希望能够针对每个浏览器标签页维护一个会话状态。

在ASP.NET中是否很容易(或者说可能)实现呢?

例如:用户在Firefox中按下Ctrl-T五次,然后在每个选项卡中访问网站。我希望每个标签页在服务器端有自己独立的会话状态。

3个回答

25
为了为一个用户提供多标签会话状态而不混乱URL,请按照以下步骤进行操作。
在您的表单加载功能中,包含以下内容:
If Not IsPostback Then
  'Generate a new PageiD'
  ViewState("_PageID") = (New Random()).Next().ToString()
End If

当你将某物保存到 Session State 中时,请包含 PageID:

Session(ViewState("_PageID").ToString() & "CheckBoxes") = D

  • 与会话ID一般情况下一样,您不能相信恶意查看者不会更改SessionID / PageID。这仅适用于所有用户都可以信任的环境中。幸运的是,ViewState比使用隐藏输入字段提供了更多的保护。
  • 在ViewState通过PostBack恢复之前,您将无法访问PageID。因此,在page_init()处理程序中您将无法访问PageID。

1
对于使用ASP.NET Web Forms的开发人员,可以通过使用ViewState而不是本机HTML隐藏字段来获得一定程度的保护,以防止恶意用户篡改PageID。默认情况下,ViewState会使用服务器机器密钥进行哈希处理,如果发布的数据不是有效哈希,则ASP.NET会抛出异常。如果会话ID被篡改,这通常会导致在下一次写入数据时创建一个新会话,因为现有会话将无效 - 尝试调用现有数据将导致空引用异常。可以检查这些或IsNewSession属性。 - pwdst
@pwdst 很好的观点,我会调整解决方案以匹配!谢谢。 - Brian Webster
2
这是一个非常出色的解决方案,用于解决我在工作中处理数据完整性时遇到的问题。用户会打开第二个标签页,然后返回更新在第一个标签页中保存的记录,当然还有与第二个记录相关联的会话数据。我使用了这个解决方案的变体来防止对错误记录进行不正确的更新。 - pwdst
也许更好的做法(或者另外一种方式)是使用隐藏字段,这样可以使JavaScript访问更加简单(例如,如果您需要向WebMethod发送值等),不是吗? - Morcilla de Arroz
当前上下文中不存在名称为“ViewState”的内容。这是@GeorgeWBush显示的错误。 - Dinav Ahire
显示剩余2条评论

17
<configuration>
  <system.web>
    <sessionState cookieless="true"
      regenerateExpiredSessionId="true" />
  </system.web>
</configuration>

http://msdn.microsoft.com/en-us/library/ms178581.aspx

在这种情况下,每个选项卡都将获得唯一的ID,并且看起来像是另一个访问者。


cookieless="true" 真的需要吗? - ErTR
@Ertürk Öztürk:这个问题听起来是“我想为每个浏览器标签页维护一个会话状态。”所有浏览器实例共享相同的 cookie。 - zerkms
@zerkms 我可以接受无 cookie,但我需要在页面加载时动态设置它。不幸的是,它是只读的。 - ErTR
1
@ErtürkÖztürk,我的建议是如果您有问题,请提出一个单独的问题。 - zerkms
4
注意:如果用户从一个标签页复制URL并将其粘贴到另一个标签页,此方法将无法正常工作。由于会话是基于URL中的密钥进行的,因此两个标签页现在将使用相同的会话。 - MyNameIsKo
显示剩余2条评论

1

使用Brian Webster的答案,我发现XMLHttpRequest存在问题。事实证明,XMLHttpRequest没有将IsPostback标志设置为true,因此请求看起来像是一个新请求,并且会为该请求创建一个新的会话状态。为了解决这个问题,我还检查了ViewState("_PageID")的值。

因此,我的C#代码如下:

protected dynamic sessionVar; //a copy of the session variable

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack && ViewState["_PageID"] == null)
    {
        ViewState["_PageID"] = (new Random()).Next().ToString();
        Session[ViewState["_PageID"] + "sessionVar"] = initSessionVar(); //this function should initialize the session variable
    }
    sessionVar = Session[ViewState["_PageID"] + "sessionVar"];
    //...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接