2012-03-07 1 views
2

У меня есть список источников информации в базе данных, которые мне нужно передать на просмотр в MVC. Мне нужен конечный пользователь, чтобы иметь возможность отмечать источники информации, которые относятся к их курсу.MVC 3 - Передача списка флажков контроллеру и обратно

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

public ViewResult CreateUpdateInfoSource(int ProgrammeId) 
     { 
      List<ProgInfoSourceModel> viewmodel = new List<ProgInfoSourceModel>(); 
      List<ProgInfoSourceDTO> myProgInfoDTOList = progInfoSourceService.AllInfoSources(); 
      if (myProgInfoDTOList.Count != 0) 
      { 
       foreach (var x in myProgInfoDTOList) 
       { 
        ProgInfoSourceModel insert = new ProgInfoSourceModel(); 
        insert.Selected = false; 
        insert.ProgrammeId = ProgrammeId; 
        insert.InfoSourceId = x.InfoSourceId; 
        insert.InfoSource = x.InfoSource; 
        insert.InfoReference = x.InfoReference; 
        insert.Rank = x.Rank; 

        viewmodel.Add(insert); 
       } 
      } 

      return View(viewmodel); 
     } 

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

Моя модель выглядит следующим образом:

namespace ProgrammeSpec.MVC.Models 
{ 
    public class ProgInfoSourceModel 
    { 
     [DisplayName("Selected")] 
     public bool Selected { get; set; } 
     [DisplayName("Programme Id")] 
     public int ProgrammeId { get; set; } 
     [DisplayName("Info Source Id")] 
     public int InfoSourceId { get; set; } 
     [DisplayName("Info Source")] 
     public String InfoSource { get; set; } 
     [DisplayName("Reference")] 
     public String InfoReference { get; set; } 
     [DisplayName("Rank")] 
     public int? Rank { get; set; } 
    } 
} 

Мой Вид выглядит следующим образом:

<html> 
<head> 
    <title>CreateUpdateInfoSource</title> 
</head> 
<body> 

@using (Html.BeginForm()) 
{ 
    <table> 
     <tr> 
      <th> 
       Selected 
      </th> 
      <th> 
       ProgrammeId 
      </th> 
      <th> 
       InfoSourceId 
      </th> 
      <th> 
       InfoSource 
      </th> 
      <th> 
       InfoReference 
      </th> 
      <th> 
       Rank 
      </th> 
      <th></th> 
     </tr> 

    @foreach (var item in Model) 
    { 
     <tr> 
      <td> 
       @Html.CheckBoxFor(modelItem => item.Selected) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.ProgrammeId) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.InfoSourceId) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.InfoSource) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.InfoReference) 
      </td> 
      <td> 
       @Html.DisplayFor(modelItem => item.Rank) 
      </td> 
      <td> 
       @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) | 
       @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) | 
       @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ }) 
      </td> 
     </tr> 
    } 


    </table> 
    <input type="submit" value="Update" /> 
} 
</body> 
</html> 

и контроллер, что вид получает передается выглядит следующим образом: (сниппета)

[HttpPost] 
     public ActionResult CreateUpdateInfoSource(List<ProgInfoSourceModel> viewmodel) 
     { 
      if (ModelState.IsValid) 
      { 
       try 
       { 

Проблема - это viewmodel is null. Я понимаю, что это, вероятно, потому, что я распаковал список в представлении, поэтому он больше не является списком, но как я могу получить доступ к значениям флажков?

Добавленная сложность заключается в том, что количество источников Ставки будет меняться, так что я не могу использовать статическую форму или список и дать каждому один идентификатор ...

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

ответ

0

Попробуйте использовать шаблон редактора (вот еще один вопрос, который отвечает на этот вопрос How to create custom editor/display templates in ASP.NET MVC 3?), для вашего ProgInfoSourceModel, а затем просто используйте Html.EditorFor(m => m.Model) на вид.

Когда вы используете цикл foreach, каждый флажок получает одинаковое имя ввода - и поэтому фактически не возвращает правильные данные.

Если вы идете по шаблону шаблона редактора и делаете MVC тяжелой работой по итерации через IEnumerable - он будет создавать входы с именами, такими как «item [0] .Selected» - то, что модельное связующее затем правильно десериализуется обратно список.

Фил Хаак также фантастический блоге прохождения именно этот сценарий еще в 2008 году: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

+0

Спасибо за это, он взял меня на несколько часов, и я наконец-то взломал. Пришлось немного почитать, но это указывало на меня в правильном направлении. Я рад, что вы не сказали мне, как это сделать, поскольку это означало, что я многому научился для ответа на этот вопрос и действительно чему-то научился! ура –

+0

@ D.Mac - я действительно рассматривал ложку кормления; но я судил по тому усилию, которое вы задали в вопросе, что вы больше заинтересованы в обучении :) –