Это также может быть результатом использования отражения. Если у вас есть код, который отражает класс, и извлекает метод по имени (например: с Class.getDeclaredMethod("someMethodName", .....)
), то в любое время, когда имя метода изменяется, например, во время рефакторинга, вам нужно будет помнить, чтобы обновить параметры до метода отражения для соответствия новой сигнатуре метода, или вызов getDeclaredMethod
вызовет NoSuchMethodException
.
. Если это причина, то трассировка стека должна показывать точку, в которой используется метод отражения, и вы Вам просто нужно обновить параметры, чтобы они соответствовали фактической сигнатуре метода.
По моему опыту это иногда возникает при модульном тестировании частных методов / полей и использовании класса TestUtilities
для извлечения полей для проверки теста. (Как правило, с устаревшим кодом, который не был разработан с учетом модульного тестирования.)
Как следует из названий методов, DropDownListFor()
предназначен для создания <select>
(для выбора 1 опции), а ListBoxFor()
предназначен для создания <select multiple>
(для выбора нескольких параметров). Хотя оба метода имеют много общего кода, они дают разные результаты.
Добавление атрибута multiple="multiple"
изменяет отображение, но оно не изменяет функциональность кода, выполняемого этими методами.
Если вы проверите исходный код , вы заметите, что все перегрузки DropDownListFor()
в конечном итоге вызовут метод private static MvcHtmlString DropDownListHelper()
, и аналогичным образом ListBoxFor()
в конечном итоге вызывает метод private static MvcHtmlString ListBoxHelper()
.
Оба эти метода называют метод private static MvcHtmlString SelectInternal()
, но разница в том, что DropDownListHelper()
проходит allowMultiple = false
, а ListBoxHelper()
проходит allowMultiple = true
.
Внутри SelectInternal()
, ключевая строка кода
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
Затем значение defaultValue
используется при построении html для элементов <option>
и используется для установки атрибута selected
(s ).
В случае ListBoxFor()
значение defaultValue
будет массивом, определенным вашим свойством SelectedAssignees
. В случае DropDownListFor()
он возвращает null
, потому что значение вашего свойства нельзя передать в string
(его массив).
Поскольку defaultValue
- null
, ни один из <option>
имеют атрибут selected
, и вы теряете привязку к модели.
Как побочная заметка, если вы должны были установить значения SelectedAssignees
в методе GET, прежде чем передавать модель на в представлении вы увидите, что ни один из них не выбран при использовании DropDownListFor()
по тем же причинам, что описаны выше.
Обратите также внимание, что код для генерации SelectList
должен быть просто
vm.TasksFilterGroup.Assignees = new SelectList(employees, "Id", "FullName" });
Нет смысла устанавливать третий параметр при использовании методов DropDownListFor()
или ListBoxFor()
, потому что его значение свойства связывается с (SelectedAssignees
), которое определяет, какие параметры выбраны (третий параметр игнорируется методами). Если вы хотите, чтобы параметры, соответствующие этим значениям Guid
, были выбраны, затем в методе GET используйте
vm.TasksFilterGroup.SelectedAssignees= new string[]{ "51b6f06a-e04d-4f98-88ef-cd0cfa8a2757", "51b6f06a-e04d-4f98-88ef-cd0cfa8a2769" };