听起来您可能正在尝试执行以下操作:
例如,假设您有一个两页的问卷,第一页上有名字,第二页上有姓氏。您希望用户可以打开两个选项卡,并在问卷的不同页面上,同时在每个选项卡的问卷中输入不同的数据。
因此,在选项卡 A 中,您输入了 Mark 作为名字并提交,您现在在选项卡 A 中的第二页。您决定也要为您的朋友做一个问卷调查,所以您打开一个新选项卡,选项卡 B . 在选项卡 B 中,您输入 Tom 并提交页面。
目前在浏览器中,您有选项卡 A,它位于问卷的第 2 页,名字 =“Mark”,选项卡 B 位于问卷的第 2 页,名字 =“Tom”。假设您想在服务器上的会话中维护这两者,我认为这是一种适合您的方法。
当网络浏览器请求表单的第 1 页时,在 GET 请求中(没有向服务器发布问卷数据),您在响应 html 中提供一个隐藏字段并生成一个随机数以存储在该字段中。提交此表单后,您在服务器上执行以下操作:
- 使用随机数作为键在会话中查找 "var questionaire = session[Request.Form["questionaire_rnumber"]]
如果问卷不在会话中,您创建一个新问卷并更新它的属性并将其粘贴在会话中
var questionaire = new Questionaire();
questionaire.FirstName = Request.Form["firstName"]
session[Request.Form["questionaire_rnumber"]] = questionaire;
如果问卷在会话中,您只需更新对象并显示下一页,但是当您显示下一页时,您将希望使用您在页面上使用的相同随机数再次在 html 中提供隐藏的随机数字段1.
这样,您可以在一个会话中持有任意数量的问卷。使用 MVC.NET,您应该直接将随机数字段添加到您的视图模型中,并添加用于在会话中查找现有问卷或创建新问卷的逻辑,我认为您会很高兴。
您还应该记住该方法可能存在的问题,例如后退按钮问题、安全问题和性能问题。
安全和性能问题的一个例子是,攻击者意识到您的应用程序是这样工作的,并且攻击者请求表单的第 1 页 10,000 次,并且每次都提交第 1 页。在一个用户会话中,您将拥有 10,000 个问卷对象。如果攻击者删除了他的会话 ID cookie 10,000 次,并且对于每个会话 ID cookie,他为页面 1 创建了 10,000 个请求并提交了页面 1 表单,那么您将在服务器上的 10,000 个会话中累积有 100,000 个问卷对象。因此,您还应该对其施加一些限制以保护您的应用程序,例如:
- 任何单独的会话只能有 X 个问卷在会话中
- 任何单独的 IP 地址只能有 Y 个并发会话(您可能需要在 Application 对象中跟踪)
对附加用例的附加响应
感谢您的用例。我的解决方案应该仍然适合你。你有两个选择。
如果您想确保只有一个选项卡与您的工作流程一起工作,那么当随机数从新选项卡传递到服务器时,您将能够检测到另一个工作流程正在进行中,并且来自新选项卡的随机数选项卡与第一个随机数不匹配,因此您将引发异常并向用户显示一些消息,说明他们在完成第一个工作流之前无法开始新的工作流,并询问他们是否要取消第一个工作流。您必须询问他们是否要取消它,因为如果他们在他们开始的第一个工作流程上关闭浏览器,他们将被卡住,直到他们的会话到期。如果他们继续尝试开始新的工作流程,这不会发生。
其次,您可以允许他们执行多个操作,但按照第一个答案中的建议,按随机数分割每个工作流的上下文。关键是你在你的会话中创建了一些小会话,但是键入了一个只存储在客户端中的值。因此,由于在表单发布到服务器时每个选项卡都有不同的随机数,因此很容易将该随机数与会话中的条目相关联,该条目包含从该选项卡启动的工作流的所有信息。
希望这可以帮助。