在ASP.NET MVC的几个向导步骤中使用数据库表实现数据持久性的最佳方法是什么?
目前我们正在使用会话在多个向导步骤/视图中保留大量数据。我们遇到了一个问题,我们怀疑会话超时是罪魁祸首。出于这个原因,我们决定用数据库表替换会话。
到目前为止,我们已确定我们需要以下内容:
当用户点击第一页时,唯一的ID /令牌(可能是 生成数据库主键,以确定数据的位置 存储在整个工作流程中此id /令牌使用 URL(如果可能的话),以便我们不需要重新实施会话
每个向导视图/步骤的单独表格。我们在每个操作中实现了逻辑,用于测试存储在会话中的向导步骤对象,以确保用户无法跳过工作流程中的步骤。使用数据库数据持久性实现类似的测试会更容易,数据分成不同的表而不是单个表
在与提供的id /令牌相关联的记录中的某处存储过期时间戳,以模仿会话超时,例如,当处理发布的表单时,如果当前日期时间大于存储的日期时间戳,则拒绝请求< / p>
使用实体框架来推送和提取数据
我们很难弄清楚如何在代码中实现它。我们遇到http://www.4guysfromrolla.com/webtech/041600-2.shtml这有点帮助,但没有真正解释如何在ASP.NET MVC控制器中实现它。
我们在下面提供了一段代码,以便了解我们目前使用会话做的事情:
控制器
[HttpGet]
public ActionResult StepOne() {
StepOneViewModel stepOneModel;
WizardViewModel wizard = (WizardViewModel)Session["Wizard"];
if(wizard == null || wizard.StepOne == null)
stepOneModel = new StepOneViewModel();
else
stepOneModel = wizard.StepOne
return View();
}
[HttpPost]
public ActionResult StepOne()
{
//validate and store data into wizard session object
}
public ActionResult StepTwo()
{
StepTwoViewModel stepTwoModel;
WizardViewModel wizard = (WizardViewModel)Session["Wizard"];
if(wizard == null || wizard.StepOne == null)
return RedirectToAction("StepOne");
if(wizard.StepTwo == null)
stepTwoModel = new StepTwoViewModel();
else
stepTwoModel = wizard.StepTwo;
Session["Wizard"] = wizard;
return View();
}
向导模型
public WizardViewModel
{
public StepOne { get; set; }
public StepTwo { get; set;}
}
实施此方法的最佳方法是什么?我们如何创建/跟踪这个确定数据来源的唯一标记?我们如何测试用户是否已完成之前的步骤并且未尝试跳过?关于如何实现这种方法的任何控制器代码/想法都值得赞赏。
答案 0 :(得分:0)
以下是我们过去实施类似模式的方法。 我在这里假设你的用户没有在系统中注册(如果它们更容易,那么)
向导的第一步是收集用户的电子邮件地址。
我们为此会话生成一个唯一令牌,并将其嵌入到url中并通过电子邮件发送给用户。用户可以使用它随时返回并完成工作流程。你需要使令牌足够大,以便人们不能去猜测随机令牌。
注意:我们实际上生成了一个令牌ID,我们在内部使用它来映射到工作流程过程。我们还生成一个嵌入到url中并发送给用户的哈希值。
我们使用普通的实体表而不是为每一步分开表,而是在这些表的顶部,我们有一个表将用户令牌链接到实体数据并指示一个状态,我们用它来确定他们走了多远。这意味着您有一个基本路线,它确定当前步骤并转移到该步骤的正确路线。
常规清理代币,即移除超过2周的代币。用户通过电子邮件发送的网址仍可正常运行,但会将其带到新工作流程,并且该令牌会重新用于新会话。
最后,如果工作流程已完成,我们可以从系统中删除令牌。
如果用户已注册到系统中,那么您无需通过电子邮件发送,只需将工作流程链接到用户。