Снова я столкнулся с ситуацией "Это не должно быть! *! # жесткое".
Проблема: я хочу использовать форму в MVC для создания объекта. Одним из элементов объекта является набор ограниченного выбора - идеальный кандидат для выпадающего списка.
Но если я использую SelectList в своей модели и выпадающий список в моем представлении, а затем попытаюсь отправить модель обратно в мой метод Create, я получаю сообщение об ошибке "Отсутствует исключение метода: нет конструктора без параметров для этого объекта". Исследуя исходный код MVC, кажется, что для привязки к модели Binder должен иметь возможность создать ее сначала и не может создать SelectList, потому что для нее нет конструктора по умолчанию.
Здесь упрощенный код: Для модели:
public class DemoCreateViewModel
{
public SelectList Choice { get; set; }
}
Для контроллера:
//
// GET: /Demo/Create
public ActionResult Create()
{
DemoCreateViewModel data = new DemoCreateViewModel();
data.Choice = new SelectList(new string[] { "Choice1", "Choice2", "Choice3" });
ViewData.Model = data;
return View();
}
//
// POST: /Demo/Create
[HttpPost]
public ActionResult Create(DemoCreateViewModel form)
{
try
{
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
И для представления:
<fieldset>
<legend>Fields</legend>
<%= Html.LabelFor(model => model.Choice) %>
<%= Html.DropDownListFor(model => model.Choice, Model.Choice) %>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
Теперь я знаю, что могу сделать эту работу, отбросив назад 10 ярдов и набрав: привязку модели обхода и возврат к FormCollection, а также проверку и привязку всех полей самостоятельно, но это будет более простой способ. Я имею в виду, это примерно так же просто, как и нужно. Есть ли способ сделать эту работу в архитектуре MVC ModelBinding? Если так, то, что это? А если нет, то как?
Edit: Ну, у меня есть яйцо на моем лице, но, возможно, это поможет кому-то другому. Я сделал еще несколько экспериментов и нашел простое решение, которое, похоже, работает.
Укажите простое значение (строка или целое число, в зависимости от того, какой тип значения выбранного списка), и укажите имя как элемент модели, к которому вы привязываетесь. Затем укажите второй элемент в качестве списка выбора вариантов и назовите его чем-то другим. Итак, моя модель стала:
public class DemoCreateViewModel
{
public string Choice { get; set; }
public SelectList Choices { get; set; }
}
И затем оператор DropDownListFor в представлении становится:
<%= Html.DropDownListFor(model => model.Choice, Model.Choices) %>
Когда я это делаю, кнопка submit правильно привязывает выбор, сделанный в форме к строке Choice, и возвращает модель ко второму методу Create.