Связывание коллекций в MVC

У меня есть модель представления, состоящая из объекта Applicant и коллекции TeamMember. Когда я отправляю модель обратно, коллекция Team всегда имеет значение null. Я пытался изменить коллекцию с моего исходного IEnumarable на List, но это не имело значения. Поэтому я изменил действие редактирования контроллеров, чтобы принять FormCollection, и проверил наличие данных в viewModel["member.FirstName"]. Я не понимаю, почему привязка не работает. Я пытался максимально очистить свои образцы кода, но я не понимаю, чего мне не хватает. Любая помощь приветствуется!

Просмотреть свойства модели

public class MyViewModel
{
    public Applicant ApplicantInfo { get; set; }
    public List<TeamMember> TeamMembers { get; set; }
}

Контроллер

[HttpPost]
public ActionResult Edit(MyViewModel viewModel)
{
         //  viewModel.ApplicantInfo has the form data
         //  viewModel.TeamMembers = null              
}

Просмотреть

<% using (Html.BeginForm())
       {%>
    <h3>
    <a href="#">Applicant Information</a>
    </h3>
    <label>
        City
        <%: Html.TextBoxFor(m => Model.ApplicantInfo.City)%>
    </label>
    <label>
        State
        <%: Html.TextBoxFor(m => Model.ApplicantInfo.State)%>
    </label>

    <h3>
    <a href="#">Team</a>
    </h3>
    <div>
    <% foreach (var member in Model.TeamMembers)
    { %>           
    <div class="editor-field">
        <%: Html.DropDownList("member.Type", Model.GetMemberTypes(member.MemberType.TypeId))%>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(m => member.FirstName)%>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(m => member.LastName)%>
    </div>
    <div class="editor-field">
        <%: Html.EditorFor(m => member.Title)%>
    </div>            
    <%} %>
    </div>
    <p>
        <input type="submit" value="Save" />
    </p>
    <% } %>

person MisterIsaak    schedule 09.02.2011    source источник


Ответы (2)


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

<% for (int i=0; i<Model.TeamMembers.Count; i++) { %>
<div class="editor-field">
  <%: Html.EditorFor(m => m.TeamMembers[i].FirstName)%>
</div>
<div class="editor-field">
  <%: Html.EditorFor(m => m.TeamMembers[i].LastName)%>
</div>
<% } %>

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

<% foreach (var member in Model.TeamMembers) { %>
  <%: Html.EditorFor(x => 
    member, 
    "TeamMember", 
    "TeamMembers["+(member.Number-1)+"]", 
    new { MemberTypes = Model.GetMemberTypes(member.MemberType.TypeId) })%>
<% } %>

Вот старая, но все еще актуальная статья от Фила Хаака по теме.

person Mayo    schedule 09.02.2011
comment
Я почти уверен, что когда я реализовал свой шаблон, мне не нужно было беспокоиться о принудительном отображении индексов и т. д. Я верю, что когда вы используете EditorFor в списке и у вас есть шаблон редактора для отдельных элементов, составляющих список , он автоматически выполняет итерацию и заботится о привязке и т. д. - person Shea Daniels; 10.02.2011
comment
Я знаю, что это работает без индексации, когда модель сама по себе является списком. Однако я столкнулся с проблемами без индексации в случае, когда модель имела список в качестве одного из своих свойств. Я, безусловно, выступаю за то, чтобы оператор попробовал, прежде чем сбрасывать со счетов. Без скобок выглядит намного чище. - person Mayo; 10.02.2011
comment
Сначала я пытался сделать это по способу Ши, но, похоже, это не сработало. Теперь, когда я снова прочитал его пост, я думаю, что не понял его. Я сделал шаблон, принимающий List<TeamMember> вместо самого TeamMember. В любом случае, я выбрал вариант индекса, и он отлично сработал. Я собираюсь посмотреть, смогу ли я заставить его работать с шаблоном, когда позволит время. Спасибо вам обоим! - person MisterIsaak; 10.02.2011
comment
Да, я столкнулся с тем же камнем преткновения. Шаблон предназначен не для списка, а для отдельного элемента списка. MVC перебирает список и использует шаблон редактора столько раз, сколько необходимо. Он автоматически добавляет перед идентификатором элемента списка имя коллекции, которой он принадлежит, и позицию элемента в коллекции. - person Shea Daniels; 10.02.2011

Попробуйте использовать это:

<%: Html.EditorFor(m => m.TeamMembers) %>

Затем создайте общий шаблон редактора с типом модели TeamMember. MVC должен справиться с привязкой всего к вашей модели просмотра при публикации для вас.

person Shea Daniels    schedule 09.02.2011