При обработке сообщений о формах в MVC я нахожу, что я пишу несколько, несколько утомительный код, чтобы убедиться, что опубликованные выпадающие списки выбраны для действительных элементов в список. Идея заключается в том, что нет ничего, что помешает сообщению, содержащему выбранный идентификатор, который не был первоначально представлен в раскрывающемся списке. Пользователь может вставить свой собственный элемент в раскрывающийся список (или иначе отправить все, что захочет), или, может быть, форма сидела в окне так долго, что элементы, которые теперь доступны, изменились. Независимо от того, почему это может произойти, факт заключается в том, что вы не можете контролировать отправленные данные. Вот пример кода, как я справляюсь с:ASP.NET MVC для проверки выбора выбранного (выпадающего) списка выбранных элементов
VM:
public class MyViewModel
{
public string SelectedItemID {get; set;}
public List<Items> AvailableItems {get; set;}
}
Вид:
@using (Html.BeginForm())
{
@Html.DropDownListFor(m => m.SelectedItemID,
Model.AvailableItems.Select(i => new SelectListItem()
{
Value = i.ID.ToString(),
Text = i.Name,
Selected = (Model.SelectedItemID == i.ID)
}), "Select One")
}
Контроллер:
[HttpPost]
public ActionResult Index(MyViewModel myVM)
{
bool isValid = true;
try
{
//Reload the available items
myVM.AvailableItems = Repository.GetAvailableItems();
if(!ModelState.IsValid)
{
isValid = false;
}
else
{
//Make sure the SelectedItemID is a real item
if(!myVM.AvailableItems.Any(i => i.ID == myVM.SelectedItemID))
{
isValid = false;
myVM.SelectedItemID = null;
ModelState.AddModelError("SelectedItemID", "Required"); //This gets interesting when the selected ID belongs to a nested VM in a collection.
}
}
if(isValid)
{
//Finally I can process the form
}
}
catch(Exception)
{
ModelState.AddModelError("", "Unable to process your submission. Please try again.");
}
//return an ActionResult
}
Установка ошибки в ModelState получает особенно некрасиво, если SelectedItemID принадлежит к вложенной модели представления, находящейся внутри коллекции. Кажется, что это должен быть стандартный тип проверки, но, относительно простоты выполнения другой проверки в asp.net MVC, это довольно уродливо и утомительно. Есть ли более простой способ позаботиться об этом?
Примечание: вы можете удалить 'Selected = (Model.SelectedItemID == i.ID)'. Ваша привязка к свойству, поэтому установка свойства 'Selected'' SelectListItem' игнорируется - это просто лишние дополнительные накладные расходы. –
@ StephenMuecke Я нашел, что это не так. Без настройки «Выбранный» раскрывающийся список выглядит пустым, если для параметра Model.SelectedItemID установлено значение, существующее в списке. – xr280xr
Тогда вы не понимаете, что делает этот метод. Вы можете установить свойство 'Selected' на то, что вам нужно, и оно будет проигнорировано. Внутренний метод 'DropDownListFor()' создает собственный новый 'IEnumerable 'и устанавливает свойство« Выбранное »на основе значения свойства, к которому вы привязываетесь. –