2

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.

4
  • Are you using HtmlHelpers to create your View? Commented May 8, 2011 at 1:48
  • I use several. Html.BeginForm, Html.DropdownFor, Html.ActionLink, Html.HiddenFor (for the step number, among other things), etc. Commented May 8, 2011 at 22:48
  • Could it be because you change the value you are switching on inside the switch statement? Try copying it into another variable and use that in your switch statement. Commented May 9, 2011 at 16:09
  • No, I don't think so. As far as I know, the semantics of switch treat the switch expression as a value, not a reference. And in any case, Html.DisplayFor(m => m.Step) and Html.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. Commented May 9, 2011 at 18:34

1 Answer 1

3

Please try to use this statement immediately before returning a view in your controller.

ModelState.Clear();

I believe this should solve your issue.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.