If I have a simple model like this:
Model:
public class AnimalModel {
public string Species {get;set;}
}
View:
<%= Html.TextBox("Species") %>
ActionMethod (POST):
AnimalModel model = new AnimalModel();
// update model
UpdateModel(model); // updates ViewData.ModeState
// correct spelling
if (model.Species == "catt") {
model.Species = "cat";
}
// return view
return View(model);
So the action method on a POST is supposed to correct the spelling of 'catt' to 'cat'.
The problem is that the source code for 'TextBox' will take the value from ViewData.ModelState if it finds a 'Species' value in there. This means that my correct value is not updated on a postback because 'catt' takes priority.
So I thought - ah well I'll just make it explicit like this :
<%= Html.TextBox("Species", Model.Species) %>
Surprisingly this doesnt work and STILL takes the value from ViewData.ModelState. I'm pretty sure this is a bug in MVC because looking at the source code for this overload i find this overload. It clearly indicates that the 'useViewData' parameter is supposed to be false if 'value' is provided (which I'm doing explicitly above) :
public static string TextBox(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) {
return InputHelper(htmlHelper, InputType.Text, name, value,
(value == null) /* useViewData */, false /* isChecked */, true /* setId */, true /* isExplicitValue */, htmlAttributes);
}
Unfortunatley though the 'InputHelper' method doesn't respect this property for a TextBox and still looks first in the ViewDataDictionary. It finds 'catt' in this dictionary because it came directly from the POST data.
I've found a solution when a UserControl is used, which passes in NULL for ViewDataDictionary.
<% Html.RenderPartial("AnimalControl", Model, null); %>
What is the solution to this? I'm sure this is documented somewhere but i cant seem to find it. I don't want to have to clear out ViewDataDictionary manually but i see no other solution.