I'm implementing a two-step wizard-like process on a web page. The operation is reassigning a student to another teacher. Because there are many teachers across many sites, the first step is to choose from a drop-down list of sites. The second step is to choose a teacher at that site.
I have a single view model, StudentReassignmentForm, with properties necessary for each step of the process, like FirstName, LastName, StudentId, TeacherId, SiteId, etc. There's also a Step property, which keeps track of which step of the process is current. The post handler looks at the step number, and updates the form to show the next step, and then shows a view for that step. The same post method handles each step of the process. Stripped down to its core, my controller methods are:
public ActionResult ReassignStudent(int studentId)
{
// ... look up student and prepare for step 1 ...
StudentReassignmentForm form = new StudentReassignmentForm();
form.Step = 1;
form.StudentId = studentId;
form.FirstName = ...;
form.LastName = ...;
form.Sites = [IList<Site> of all sites]
return View("ReassignStudent1", form);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ReassignStudnet(StudentReassignmentForm form)
{
switch(form.Step)
{
case 1:
// Prepare for step 2 by looking up teachers at chosen site
form.Teachers = [IList<Teacher> of teachers at the site]
form.Step = 2;
return View("ReassignStudent2", form);
break;
case 2:
// Make final reassignment
// ...
}
}
The first step works fine. I can pick the site, and on the postback, form.SiteId is properly set.
The problem is that although I'm explicitly setting form.Step = 2, the view ReassignStudent2 is rendered with step value of 1. Uisng Fiddler, I see that what's going from the server to the browser is the value 1 (so it's not the view that's going wrong somehow).
EDIT: clarified problem in title
EDIT
I've done some more experimenting, and found that if I change my view to use Html.DisplayFor(m => m.Step) instead of Html.HiddenFor(m => m.Step), it renders the correct current step value of 2 instead of the old step value of 1. Then I tried Html.EditorFor(m => m.Step), and it produced the incorrect value of 1 also.
My POST handler uses the same model instance both as an input and as an output. The system creates a StudentReassignmentForm from the POST data, then I change some values, add some others, and use it to render the view for the next step. Is that a supported scenario? I wonder if the problem is related to caching the values of the lambda expressions (which I assume is done for performance). Maybe Html.HiddenFor and Html.EditorFor are picking up a stale cached value.
In any case, I see my workaround, which is just to hard-code the step number in my views.
switching on inside theswitchstatement? Try copying it into another variable and use that in yourswitchstatement.switchtreat the switch expression as a value, not a reference. And in any case,Html.DisplayFor(m => m.Step)andHtml.HiddenFor(m => m.Step)produce different results when rendered next to each other. I see the correct step number in the form object that's sent to the view.