I have a multi-step registration process, backed by a single object in domain layer, which have validation rules defined on properties.
To supplement on Amit Bagga's answer you will find below what I did. Even if less elegant I find this way simpler than Darin's answer.
Controller :
public ActionResult Step1()
{
if (Session["wizard"] != null)
{
WizardProductViewModel wiz = (WizardProductViewModel)Session["wizard"];
return View(wiz.Step1);
}
return View();
}
[HttpPost]
public ActionResult Step1(Step1ViewModel step1)
{
if (ModelState.IsValid)
{
WizardProductViewModel wiz = new WizardProductViewModel();
wiz.Step1 = step1;
//Store the wizard in session
Session["wizard"] = wiz;
return RedirectToAction("Step2");
}
return View(step1);
}
public ActionResult Step2()
{
if (Session["wizard"] != null)
{
WizardProductViewModel wiz = (WizardProductViewModel)Session["wizard"];
return View(wiz.Step2);
}
return View();
}
[HttpPost]
public ActionResult Step2(Step2ViewModel step2)
{
if (ModelState.IsValid)
{
//Pull the wizard from session
WizardProductViewModel wiz = (WizardProductViewModel)Session["wizard"];
wiz.Step2 = step2;
//Store the wizard in session
Session["wizard"] = wiz;
//return View("Step3");
return RedirectToAction("Step3");
}
return View(step2);
}
public ActionResult Step3()
{
WizardProductViewModel wiz = (WizardProductViewModel)Session["wizard"];
return View(wiz.Step3);
}
[HttpPost]
public ActionResult Step3(Step3ViewModel step3)
{
if (ModelState.IsValid)
{
//Pull the wizard from session
WizardProductViewModel wiz = (WizardProductViewModel)Session["wizard"];
wiz.Step3 = step3;
//Save the data
Product product = new Product
{
//Binding with view models
Name = wiz.Step1.Name,
ListPrice = wiz.Step2.ListPrice,
DiscontinuedDate = wiz.Step3.DiscontinuedDate
};
db.Products.Add(product);
db.SaveChanges();
return RedirectToAction("Index", "Product");
}
return View(step3);
}
Models :
[Serializable]
public class Step1ViewModel
{
[Required]
[MaxLength(20, ErrorMessage="Longueur max de 20 caractères")]
public string Name { get; set; }
}
[Serializable]
public class Step2ViewModel
{
public Decimal ListPrice { get; set; }
}
[Serializable]
public class Step3ViewModel
{
public DateTime? DiscontinuedDate { get; set; }
}
[Serializable]
public class WizardProductViewModel
{
public Step1ViewModel Step1 { get; set; }
public Step2ViewModel Step2 { get; set; }
public Step3ViewModel Step3 { get; set; }
}