围绕多个选项卡窗口共享的ASP.NET会话

时间:2010-05-13 18:19:17

标签: .net asp.net

我在第一页的asp.net会话中存储了一些值。在下一页上,正在读取此会话值。但是,如果打开了多个选项卡并且有多个页面1->第2页导航,则会话中存储的值会混淆,因为会话在浏览器选项卡之间共享。

我想知道这有什么选择:

  1. 查询字符串:使用查询字符串在页面之间传递值,我不想采用这种方法,因为第1页上可能有多个锚标记链接到第2页,我不能重写每个标签,因为它们是动态的。

  2. 缓存???内存中的cookie也可以在浏览器选项卡中共享,与会话cookie,rite?

  3. 相同

    还有其他选择吗?

    PS:第1页到第2页不是表单提交。

6 个答案:

答案 0 :(得分:14)

我想出了一个解决方案:

  1. 通过将guid值分配给 window.name 属性,使用Javascript为浏览器窗口/选项卡分配一个像guid一样的唯一ID。 window.name属性对于每个浏览器窗口/选项卡都是唯一的,不会在窗口之间共享。

  2. 使用guid作为密钥,通过Web服务读取和写入ASP.NET会话数据。由于javascript无法访问asp.net会话,因此您需要使用Web服务并通过javascript调用它的方法。

  3. 可以通过JSON在javascript和webservice之间传输数据。

答案 1 :(得分:7)

  1. 为每个页面指定一个guid。将guid存放在隐藏的区域中。
  2. 使用此guid作为会话密钥,该会话密钥存储包含该页面的所有变量等的结构。
  3. 您现在可以为特定页面“呈现”提取信息,并将数据传递到会话结构中,以便代码隐藏中的新“呈现”。
  4. 这类似于 ViewState 自动执行的操作。

    编辑

    评论回复

    我不认为你描述它可能是

    在您的问题中,您提到了第1页到第2页导航。如果用户在浏览器中键入第2页的URL,那么如何将当前页面2呈现与上一页1相关联?

    您需要执行某些操作,除非代码隐藏可以搜索已停止在第1页的未完成工作流列表,并将其用作新页2呈现的上一个guid 值。

    评论回复2

    您可以在页面上找到所有链接并修改它们,但它暗示出现了问题(在我看来)。但...

    http://www.extremeexperts.com/Net/Articles/LoopingthroughControls.aspx

    为您提供一种处理页面上所有控件的简单方法。您可以轻松地测试控件是否是超链接。并非所有链接都需要 runat =“server”参数设置才能生效。

答案 2 :(得分:3)

您可以使用ViewState而不是SessionState吗?

<强>更新

或者可能是ViewState和SessionState的组合。

以下是一个示例序列:

  • 在第1页上,用户选择“红色”。值存储在SessionState中。
  • 用户导航到第2页。值从SessionState读取并存储在第2页的ViewState中。
  • 用户在新标签页中打开第二页,然后选择“蓝色”。值存储在SessionState中,因此“Red”将替换为“Blue”。
  • 用户导航到第2页。同样,从SessionState读取值并存储在ViewState中。
  • 用户返回原始页面(第一个选项卡上的那个)并执行PostBack。值从 ViewState 读取。价值仍然是“红色”。
  • 用户返回第二页(第二个标签之一)并执行PostBack。值从 ViewState 读取。价值仍然是“蓝色”。

换句话说,在页面之间使用SessionState进行转换。将ViewState用于同一页面的PostBack。

这有帮助吗?

答案 3 :(得分:1)

听起来您希望每个页面保持自己的值,彼此分开。

  • 如果您可以使用Post(例如:您可以不在客户端上操纵URL),隐藏的输入标记可以很好地完成工作。你肯定想要封装它,因为手动操作会是一个巨大的痛苦。否则:
  • 如果您正在使用 ViewState ,则可以使用它。否则:
  • 您可以在网址中获取值或ID(可能更好。见下文)。万不得已,因为人类将能够搞砸了。或者他们可能会将它加入书签并在一周后回来时引起混淆。

如果无法将值发送到客户端,则需要将“PageSessionID”或其他内容传递给客户端。这个ID要么是一个guid(如果安全性是一个问题就更好),或者是一种保证唯一性的方式。以隐藏的输入标记或ViewState(或没有其他选择的url)发送到客户端,并根据该ID在服务器上存储相关数据。

Cookie不适合您。

答案 4 :(得分:1)

另一种方法是使用Server.Transfer或CrossPagePostBack。然后,您可以使用Page.PreviousPage访问所有上一页的变量。如果Page.PreviousPage为null,您知道用户直接进入该页面,您应该考虑到这一点处理第2页。

我不能真的推荐它,因为使用Server.Transfer你不会更新浏览器中的URL而CrossPagePostBack会使所有内容都回发,这可能会导致后退按钮无法“正常”工作等问题。 / p>

答案 5 :(得分:0)

我正在设计一个这样的asp.net系统,允许在一台或多台机器上有多个页面,标签,会话,使用向导界面创建和编辑基于一小段sql记录的基于guid的键请求这基本上是一个长期运行的Web应用程序,用于保存数据,这些数据仅在用户提交时才写入数据库。我们不希望由多个用户或标签编辑相同的数据。

我计划使用guid键创建/声明存储在appstate中的锁定对象。锁对象也有userid / timestamp / PageToken。页面标记是一个guid,但如果为同一会话中的另一个页面预先创建基于页面标记的会话对象,则可以为null [因此可以将更多数据传递到新页面],或者可以对会话对象的创建进行评估对于当前页面。当基于密钥创建会话对象时,它可用于存储正常的会话类型数据,该数据现在对于此密钥是唯一的,而不是在整个会话中共享。

因此,第一页在app状态下创建了一个关键对象w / o pagetoken,然后链接到新页面,该页面使用带有密钥的查询字符串从appstate中获取密钥对象,并将userid / timestamp / PageToken与null或有价值的令牌。如果匹配并且是空令牌,则会创建令牌并将其存储在密钥对象和视图状态中。

如果另一个页面带有与guid键匹配的相同查询字符串,它可以尝试声明appstate键对象但是会失败,除非在得到页面令牌的密钥对象中具有相同的用户ID /时间戳/ PageToken视图状态。如果一切都匹配,则更新时间戳。如果时间戳太旧,15分钟,则密钥对象可能被盗。如果旧页面返回查找它,则页面令牌将不再匹配,并且由于时间戳太旧或页面令牌不匹配,声明将失败。

创建密钥对象时,令牌可以为null或值。如果它在创建时开始为null,那么任何人都可以使用新令牌声明但必须匹配时间戳非常接近。

然后,相关的密钥对象可以是更大的大小,使用页面标记作为会话数据的密钥存储在会话中,例如可串行化的字典,以防需要sql后备存储。

因此,我们可以在整个Web应用程序中锁定所有用户的数据,我们可以在不使用15分钟后过期并回收锁定,并为标签页,新会话和不同浏览器提供基于密钥的数据。