I am having an issue changing the value of a text box in MVC 3.
I have a simple view that is returned by a controller and is typed to a custom view model. There is a text box on the view that is bound to a string property on the view model. If I populate this string on initial load then the text box value contains the value of the string. However, if I then post a form back to the same URL and change the view model string value and reload the view then the text box contains the value that was posted back, not the value that the controller supplied for the view model.
I created a simple test project to recreate the issue in the simplest way possible.
View Model:
http://www.codetunnel.com/content/images/textboxproblem/ViewModel.jpg
Controller:
http://www.codetunnel.com/content/images/textboxproblem/Controller.jpg
View:
http://www.codetunnel.com/content/images/textboxproblem/View.jpg
In the view I display the view model string value and I also bind the string property to a text box.
On initial load everything looks fine:
http://www.codetunnel.com/content/images/textboxproblem/InitialLoadTest.jpg
However, if I change the value of the text box and then press enter to POST the form things do not happen as I expected. The displayed value is the value the controller set in the action method, but the text box retains the value that was posted back:
http://www.codetunnel.com/content/images/textboxproblem/POSTTest.jpg
I’m not sure what the problem is.
That is (unfortunately) the correct behavior. When using
TextBoxForor other data-bound elements, the created element is first bound against the existingModelState, before it is bound against the model.The solution is to clear the ModelState in your [HttpPost] action, so that the elements in the View returned by the POST action will be bound against the model. In your POST action, add the following:
Personally, I think the design is incorrect, but clearing ModelState will give you the behavior you expected.