What is the is the best approach to implement data persistence using database tables over several wizard steps in ASP.NET MVC?
At the moment we are using a session to persist alot of data across several wizard steps/views. We are experiencing an issue and we suspect that session timeouts are to blame. For this reason we have decided to replace sessions with database tables.
So far we've established that we need the following:
When the user hits the first page a unique id/token (possibly database primary key) is generated that will determine where data is stored throughout the workflow. This id/token is persisted using the URL, if at all possible, so that we don't need to re implement sessions
Separate tables for each wizard view/step. We have implemented logic in each action that test wizard step objects stored in the session to ensure that the user can't skip steps in the workflow. Implementing similar testing with database data persistence would be easier with data separated into different tables as opposed to a single table
Storing an expiration time stamp somewhere in the record associated with the provided id/token as to imitate session timeouts e.g when processing the posted form if the current date time is greater than the stored date time stamp deny the request
Use entity framework to push and pull data
We are just having a hard time figuring out how to implement this in code. We came across https://web.archive.org/web/20211020145945/https://www.4guysfromrolla.com/webtech/041600-2.shtml which was somewhat helpful but didn't really explain how to implement it in an ASP.NET MVC controller.
We have provided a snippet of code below to provide some understanding of how we are currently doings things using sessions:
Controller
[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();
}
Wizard Model
public WizardViewModel
{
public StepOne { get; set; }
public StepTwo { get; set;}
}
What is the best way to implement this approach? How do we create/track this unique token that determines where data is pulled from? How do we test that users have completed previous steps and not tried to skip? Any controller code/thoughts on how we can implement this approach are appreciated.