ASP.Net MVC web application: Html.DisplayFor and Html.HiddenFor give different results
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(Http开发者_如何学PythonVerbs.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.
Please try to use this statement immediately before returning a view in your controller.
ModelState.Clear();
I believe this should solve your issue.
精彩评论