Asp.net MVC- Невозможно привязать значения к Multiselect [duplicate]

Это также может быть результатом использования отражения. Если у вас есть код, который отражает класс, и извлекает метод по имени (например: с Class.getDeclaredMethod("someMethodName", .....)), то в любое время, когда имя метода изменяется, например, во время рефакторинга, вам нужно будет помнить, чтобы обновить параметры до метода отражения для соответствия новой сигнатуре метода, или вызов getDeclaredMethod вызовет NoSuchMethodException.

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

По моему опыту это иногда возникает при модульном тестировании частных методов / полей и использовании класса TestUtilities для извлечения полей для проверки теста. (Как правило, с устаревшим кодом, который не был разработан с учетом модульного тестирования.)

8
задан RJBreneman 21 November 2016 в 18:03
поделиться

1 ответ

Как следует из названий методов, 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" };
18
ответ дан Stephen Muecke 16 August 2018 в 00:12
поделиться
  • 1
    Этот тщательный и хорошо осведомленный ответ очень ценится. Спасибо. – RJBreneman 22 November 2016 в 17:57
  • 2
    Это большой и глубокий ответ. Очень проницательный. – CodingYoshi 11 January 2017 в 00:34
  • 3
    Спасибо, очень хорошо описано. – Marek Czaplicki 4 July 2018 в 12:01
Другие вопросы по тегам:

Похожие вопросы: