Как я уже писал в комментарии, помощник тега select будет использовать элемент asp-for
для привязки к модели представления.Это означает, что значение модели в указанном свойстве используется для сопоставления со значением доступных элементов помощника по тегам, чтобы определить, какие элементы выбраны в данный момент.Этот процесс работает независимо от того, что SelectListItem
имеет свойство Selected
, установленное на true
.
Это означает, что если вы не используете asp-for
, то вы можете полностью выполнить эту работу так, как вам нравится:
// in the controller action
return View(new TaskEditViewModel
{
ProjectId = new List<SelectListItem>()
{
new SelectListItem { Text = "Item 1", Value = "value-1" },
new SelectListItem { Text = "Item 2", Value = "value-2", Selected = false },
new SelectListItem { Text = "Item 3", Value = "value-3" },
new SelectListItem { Text = "Item 4", Value = "value-4" },
},
});
// in the view
<select class="form-control" asp-items="Model.ProjectId"></select>
Если вы выполните это, это будет обработанный вывод:
<select class="form-control">
<option value="value-1">Item 1</option>
<option value="value-2">Item 2</option>
<option selected="selected" value="value-3">Item 3</option>
<option value="value-4">Item 4</option>
</select>
Только если вы добавите asp-for
, это перестанет работать.
<select class="form-control" id="ProjectId" multiple="multiple" name="ProjectId">
<option value="value-1">Item 1</option>
<option value="value-2">Item 2</option>
<option value="value-3">Item 3</option>
<option value="value-4">Item 4</option>
</select>
Это потому, что теперь форма отображает элемент управления формы для свойства, представляющего собой список чего-либо.Таким образом, помощник по тегам предполагает, что он должен отображать выборку, позволяющую множественные выборки.Кроме того, логика теперь будет пытаться сопоставить SelectListItem.Value
со значением Model.ProjectId
и использовать его только для определения, выбрано ли что-либо.
Как отмечено в комментариях, это не так, как выобычно здесь используется помощник по тегу select.Вместо этого у вас будет отдельное свойство для выбранного значения и отдельное свойство для доступных элементов:
public class TaskEditViewModel
{
// …
public string ProjectId { get; set; }
public IEnumerable<SelectListItem> AvailableProjects { get; set; }
}
// in the controller
return View(new TaskEditViewModel
{
ProjectId = "value-3",
AvailableProjects = new List<SelectListItem>()
{
new SelectListItem { Text = "Item 1", Value = "value-1" },
new SelectListItem { Text = "Item 2", Value = "value-2" },
new SelectListItem { Text = "Item 3", Value = "value-3" },
new SelectListItem { Text = "Item 4", Value = "value-4" },
},
});
// in the view
<select asp-for="ProjectId" class="form-control" asp-items="Model.AvailableProjects"></select>
Теперь вот HTML-код, который вы получите:
<select class="form-control" id="ProjectId" name="ProjectId">
<option value="value-1">Item 1</option>
<option value="value-2">Item 2</option>
<option selected="selected" value="value-3">Item 3</option>
<option value="value-4">Item 4</option>
</select>
Обратите внимание, что элемент 3 теперь неявно выбран, хотя его SelectListItem
не имеет установленного свойства Selected
.Это потому, что текущее значение ProjectId
в модели оказывается равным Value
из SelectListItem
.И именно в этом и заключается логика.
Этот подход имеет огромное преимущество по сравнению с использованием свойства Selected
в SelectListItem
: теперь очень ясно, какие данные отправляются при отправке формы.Поскольку значение выбранного option
- это то, что отправляется, а name
тега select
- это ключ, для которого используется значение, отправка формы будет эффективно отправлять ProjectId=value-3
сейчас.
И когда эта модель затем связывается как часть действия POST в контроллере, это значение можно правильно десериализовать в свойство ProjectId
вашей модели:
[HttpPost]
public IActionResult Edit(TaskEditViewModel model)
{
var selectedProject = model.ProjectId; // "value-3"
// …
}