Как отправить выбранное значение списка выбора в контроллер, используя модель представления? - PullRequest
1 голос
/ 10 февраля 2011

Этот вопрос задавался в разных формах, но ни один из ответов, похоже, не подходит к моей ситуации.Я просто пытаюсь получить выбранное значение раскрывающегося списка в моем контроллере.

Вот мой код:

ViewModel.cs

public class ViewModel
{
  public ViewModel() {}
  public ViewModel(Contact contact, IEnumerable<State> states)
    {
      this.Contact = contact;
      this.States = new SelectList(states, "Id", "Name", contact.StateId);
    }
  public Contact Contact {get;set;}
  public SelectList States {get;set;}
}

Controller.cs

[HttpPost]
public ActionResult Edit(ViewModel viewModel)
{
  _contactService.UpdateContact(viewModel.Contact);
  return RedirectToAction("Item", new {id = viewModel.Contact.Id});
}

View.cshtml

<button type="submit" onclick="javascript:document.update.submit()"><span>Update</span></button>//aesthic usage. 
@{using (Html.BeginForm("Edit", "Controller", FormMethod.Post, new { name = "update" }))
  {
   @Html.HiddenFor(m => m.Contact.Id)
   @Html.LabelFor(m => m.Contact.Name, "Name:")
   @Html.TextBoxFor(m => m.Contact.Name)

   <label for="state">State:</label>
   @Html.DropDownList("state", Model.States)
}
}

Все работает как положено, за исключением того, что никакие значения из выпадающего списка не передаются в моей опубликованной viewModel в контроллер.Страница редактирования и все поля загружаются правильно.Выпадающие списки привязываются правильно и их выбранные значения отображаются правильно.Однако, когда я публикую сообщение, я получаю только объект «Контакт», который передается в контроллер.Объект «Состояния» SelectList имеет значение null.

Я попытался сопоставить свойство «StateId» в своем конструкторе viewModel, но это тоже не сработало.Что я делаю не так?

Спасибо.

Ответы [ 2 ]

3 голосов
/ 10 февраля 2011

Я ненавижу отвечать на свои вопросы, но, основываясь на множестве вопросов, которые я сочетаю с множеством доступных ответов, я подумал, что суммирую свои выводы.

Прежде всего, спасибо за Филиппа, его ответ точно не решил мою проблему, но привел меня в правильном направлении. + 1

Если вы создаете форму для просмотра и редактирования, которая требует раскрывающегося списка, вот несколько советов и ошибок. Я начну со списка параметров, которые мне нужны, чтобы соответствовать моим потребностям.

  1. Сильно типизированные представления на мой взгляд предпочтительнее. Минимизируйте магические струны.
  2. Модели представлений должны содержать как можно меньше логических и посторонних элементов. Там только работа должна облегчить сбор объектов данных.
  3. В раскрывающемся списке должно отображаться выбранное значение.
  4. Выбранное значение должно легко отображаться обратно в модель представления при отправке формы.

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

ViewModel.cs

public class ViewModel
{
  public ViewModel() {}
  public ViewModel(Contact contact, IList<State> states)
  {
//no need to pass in a SelectList or IEnumerable, just what your service or repository spits out
    this.Contact = contact;
    this.States = states;
  }
  public Contact Contact {get;set;}
  public IList<State> States {get;set;}
}

Controller.cs // ничем не отличается от описанного выше

public ActionResult Edit(int id)
{
  var contact = _contactService.GetContactById(id);
  var states = _stateService.GetAllStates();
  return View(new ViewModel(contact, states));
}

public ActionResult Edit(ViewModel viewModel)
{
  _contactService.UpdateContact(viewModel.Contact);
  return RedirectToAction("Edit", new {id = viewModel.Contact.Id });
}

Просмотр // спасибо Artirto в этом сообщении

@{using (Html.BeginForm("Edit", "Controller", FormMethod.Post))
 {
  @Html.HiddenFor(m => m.Contact.Id)
  @Html.DropDownListFor(m => m.Contact.StateId, new SelectList(Model.States, "Id", "Name", @Model.Contact.StateId))
<input type="submit" value="Save" />
}
}
2 голосов
/ 10 февраля 2011

Попробуйте использовать @Html.DropDownListFor вместо этого, если «состояние» является частью вашей модели, вы можете использовать его следующим образом:

@Html.DropDownListFor(m => m.Contact.StateId, Model.States, "-- Please select a State --"), где m.State содержит выбранное значение.

Также, чтобы не путать IEnumerable с моделью, я бы поместил это в ViewBag / ViewData.

Вместо этого он будет выглядеть примерно так:

@Html.DropDownListFor(m => m.Contact.StateId, (IEnumerable<string>)ViewBag.States, "-- Please select a State --")

И в вашем действии, которое возвращает это представление, вам нужно инициализировать состояние, перечисляемое свойству ViewBag.States.

...