A simple scenario that I've never seen before, but a colleague has just hit - MVC3
- Create an action method MyAction(int myProperty = 0)
- Create a model that has a property MyProperty
- Pass an instance of this model to a strongly typed view, but set the property to 10 in code (don't use the query string parameter!)
- In the view, Html.TextBoxFor(x => x.MyProperty)
This should render 10 in the text box.
Now call the action method MyAction?myProperty=8
Shouldn't this still render 10 in the text box?
I see that I can override the property discovered by the expression and assume this is because they are the same name (Query String
parameter and model property). Eveything is then in the ViewData
but one overrides the other.
Is this by design?
This is by design - ModelState is the highest priority value-provider for model properties, higher than even model itself. Without query string parameter, ModelState does not contain value for MyProperty
, so framework uses model value.
You can use ModelState.Remove("MyProperty")
to ensure using model value
If you look at the source code for Html.TextBoxFor
you will see that if a value exists in ModelState
then it will always use that value before any other.
string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName, format) : valueParameter), isExplicitValue);
If the value is in ModelState, then it doesn't matter what you set in code.