ASP.NET MVC 3 — DropDownListFor завершается с ошибкой, когда параметр URL-адреса также существует с тем же именем, что и параметр модели представления

Я не уверен, является ли это ошибкой с расширением DropDownListFor или чем-то еще, но у нас было следующее:

http://mydomain.com/path/page?myparam=myvalue

В моей модели просмотра у меня есть следующее:

public string MyParam { get; set; }
public List<SelectListItem> ParamOptions { get; set; }

Когда я делаю следующее в своем представлении, мне не удается выбрать правильное значение:

@Html.DropDownListFor(x => x.MyParam, Model.ParamOptions, "Select Value")

Однако, когда я изменяю параметр «MyParam» в моей модели представления на «MyParam2» и обновляю свое представление, чтобы вместо этого использовать параметр MyParam2, он выберет правильный элемент параметра с учетом значения MyParam2. Раньше этого не было, когда имя параметра было MyParam.

Кто-нибудь еще столкнулся с этим? Это ошибка с MVC 3 или это плохая реализация с моей стороны?


person Brandon    schedule 23.02.2012    source источник
comment
Вы явно передаете модель в представление, как в: return View(viewModel)?   -  person swannee    schedule 23.02.2012
comment
Правильный. return View("ViewName", model);   -  person Brandon    schedule 23.02.2012
comment
Нет, это мое действие GET Index.   -  person Brandon    schedule 23.02.2012
comment
Каким должно быть выбранное значение? Модель.MyParam? Вы случайно не устанавливаете ViewData["MyParam"] или ViewBag.MyParam в контроллере? Будет полезно, если вы покажете нам код контроллера.   -  person Max Toro    schedule 23.02.2012


Ответы (3)


Как насчет упомянутого URL,

http://mydomain.com/path/page?myparam=myvalue

URL-адрес имеет строку запроса с ключом «myparam», поскольку имя совпадает с именем свойства, и когда URL-адрес вызывается, он добавит значение ModelState к «myparam».

ModelState["myparam"] будет "myvalue".

Поэтому, когда страница загружается, в раскрывающемся списке будет выбрано «myvalue» из раскрывающегося списка.

person Manas    schedule 23.02.2012
comment
Верно, но параметры запроса не должны автоматически передаваться в представление ответа. Он должен учитывать переданную модель представления, если я чего-то не понимаю. - person swannee; 23.02.2012
comment
Нет, в представлении данные имеют наивысший приоритет. Поскольку в действии получения ModelState обновляется для MyParam, MyValue отображается в раскрывающемся списке. Это та же причина, по которой в сообщении формы, если вы обновите какое-либо значение свойства и вернете ту же форму представления, все равно будет отображаться старое значение. Если вы не можете изменить строку запроса URL-адреса, удалите значение из состояния модели, например ModelState.Remove(myparam) - person Manas; 23.02.2012
comment
@swannee - короткий ответ: всегда побеждает ModelState. Это не ошибка, просто ограничение дизайна. Это хорошо известно, и это не собирается меняться. Это по дизайну. - person Erik Funkenbusch; 23.02.2012

Это хорошо известная проблема. Это не ошибка, потому что так задумано. Это скорее конструктивное ограничение.

С этим ничего нельзя поделать, просто переименуйте свой параметр или переименуйте свойство.

person Erik Funkenbusch    schedule 23.02.2012
comment
Переименовать параметр модели было проще, чем обновить параметр URL (благодаря общедоступной документации). - person Brandon; 23.02.2012

Это не очень большой ответ, кроме как сказать, что я испытал такое же поведение в немного другой ситуации.

В моем случае я вызывал дочернее действие из родительского действия и передавал модель представления, специфичную для дочернего действия, которая разделяла некоторые из тех же имен свойств с родительским ViewData. Когда частичное представление моего дочернего действия отображалось, оно показывало данные представления из родительского контроллера, а не то, что было в модели представления, которую я передал дочернему действию. В этой ситуации выглядело так, как будто данные представления из родительского действия загрязняли мою модель представления дочернего действия, когда оба свойства имели одинаковые имена.

Таким образом, похоже, что привязка иногда путается в отношении того, какое значение привязывать, когда возникают конфликты имен. В моем случае я просто переименовал свойства в дочерней модели представления, чтобы предотвратить это столкновение, но это заставило меня рвать на себе волосы, выясняя, почему там было неправильное значение.

Если у кого-то есть реальный ответ, почему это происходит, я тоже хотел бы знать. Мне это кажется ошибкой привязки, но, возможно, здесь есть намерение.

person swannee    schedule 23.02.2012