Reputation: 3694
I have a form that I'm working on in ASP MVC, and I'd like to persist the data between pages (obviously).
At the moment, I'm using a big view model that contains all fields from the entire form. I then have an action for each step of the form:
// STEP ONE
public ActionResult Step1(MyViewModel model)
{
return View("Step1", model);
}
// STEP TWO
public ActionResult Step2(MyViewModel model)
{
return View("Step2", model);
}
// STEP THREE
public ActionResult Step3(MyViewModel model)
{
return View("Step3", model);
}
// STEP FOUR
public ActionResult Step4(MyViewModel model)
{
return View("Step4", model);
}
Each form on each page has the action set to the next step, so Step1.cshtml contains a form wherein the action attribute is pointing to step 2.
The problem is, if there's a server-side validation error detected during Step 2, I have no way of sending the user back to Step 1 without losing state.
Does anyone have a relatively tidy solution for this? I've already considered, and would like to avoid, the following if possible:
Using JavaScript to create the illusion of multiple pages, while actually only managing a single form. This really won't work for me as if there are server-side validation errors at the end of Step 1, it will only be detected in Step 4 and it will completely ruin the flow of the form.
Adding an if-condition to select the view depending on the ModelState. This is problematic because it means the view will be out of sync with the URL: i.e. a submit from step 1 will load step 2, which will show the view from step 1. This is likely going to create confusion for the users.
If anyone does have any nice solutions for what I can only assume must be a pretty common problem, I'd love to hear them. Other solutions I've found here seem to fall into one of the above two answers, neither of which will work for me.
Upvotes: 0
Views: 1855
Reputation: 9391
Lets say you class structure is like this...
public class MyViewModel
{
public class Step1 { get; set;}
public class Step2 { get; set;}
public class Step3 { get; set;}
public class Step4 { get; set;}
}
You can just validate part of your model and redirect the user
public ActionResult Step2(MyViewModel model)
{
//Validate the first step
if(TryValidateModel(model.Step1)
{
//The details entered in step 1 are validate to move on to step 2
return View("Step2", model);
}
//Failed validation redirect to form one and display the errors
return RedirectToAction("Step1", model)
}
Hope this helps
Upvotes: 2