Is this by design in MVC Model Binding?

2019-02-19 18:49发布

A simple scenario that I've never seen before, but a colleague has just hit - MVC3

  1. Create an action method MyAction(int myProperty = 0)
  2. Create a model that has a property MyProperty
  3. 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!)
  4. 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?

2条回答
Ridiculous、
2楼-- · 2019-02-19 19:33

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

查看更多
三岁会撩人
3楼-- · 2019-02-19 19:53

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.

查看更多
登录 后发表回答