Это по дизайну в MVC Model Binding?

Простой сценарий, который я никогда раньше не видел, но коллега только что нажал - MVC3

  • Создать метод действия MyAction (int myProperty = 0)
  • Создайте модель, у которой есть свойство MyProperty
  • Передайте экземпляр этой модели строго типизированному представлению, но установите для этого свойства значение 10 в коде (не используйте параметр строки запроса!)
  • В представлении Html.TextBoxFor(x = > x.MyProperty)

Это должно отображать 10 в текстовом поле.

Теперь вызовите метод действия MyAction? myProperty = 8

Не должно ли это отображаться 10 в текстовом поле?

Я вижу, что я могу переопределить свойство, обнаруженное этим выражением, и предположить, что это одно и то же имя (Query String параметр и свойство модели). Eveything затем находится в ViewData, но один переопределяет другой.

Это по дизайну?

Ответ 1

Это по дизайну - ModelState - поставщик значений с наивысшим приоритетом для свойств модели, выше, чем сама модель. Без параметра строки запроса ModelState не содержит значения для MyProperty, поэтому среда использует значение модели.

Вы можете использовать ModelState.Remove("MyProperty") для обеспечения использования значения модели

Ответ 2

Если вы посмотрите на исходный код для Html.TextBoxFor, вы увидите, что если значение существует в ModelState, оно всегда будет использовать это значение перед любым другим.

string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName, format) : valueParameter), isExplicitValue);

Если значение находится в ModelState, то не имеет значения, что вы установили в коде.