2016-05-27 2 views
5

Я пытаюсь создать очень простую форму, чтобы отправить обратно некоторые значения из коллекции моделейModelBinding на коллекции модели

Когда я нажмите на кнопку отправить, и посмотреть на коллекции вернулся он не содержит каких-либо объектов. Я также вижу, что asp-for не генерирует индекс коллекции, который я ожидал.

У меня есть простая модель

public class CustomModel 
{ 
    public int Id { get; set; } 
    public string Question { get; set; } 
    public string Answer { get; set; } 
} 

И это мой взгляд

@model ICollection<CustomModel> 
<form asp-action="Index" asp-controller="Home" method="POST"> 
<table> 
    @foreach (var m in Model) 
    { 
     <tr> 
      <td><label asp-for="@Model">@m.Question</label><input asp-for="@m.Answer"/></td> 
     </tr> 
    } 
</table> 
<input type="submit" value="save" /> 

Пример того, как это будет выглядеть, когда страница renderd:

<tr> 
      <td><label>Your name?</label><input type="text" id="m_Answer" name="m.Answer" value="" /></td> 
     </tr> 
     <tr> 
      <td><label>Your Age?</label><input type="text" id="m_Answer" name="m.Answer" value="" /></td> 
     </tr> 

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

Что я здесь делаю неправильно? Это ошибка или по дизайну?

тестовый проект Github https://github.com/lasrol/TestModelBindingList

ответ

4

Изменить модель для @model List<CustomModel> И чем использовать следующий подход

<form asp-action="Index" asp-controller="Home" method="POST"> 
<table> 
    @for (int i = 0; i < Model.Count; i++) 
    {    
     <tr> 
      <td> 
       <input type="hidden" asp-for="@Model[i].Id" /> 
       <input type="hidden" asp-for="@Model[i].Question" />    
       <label asp-for="@Model[i].Question">@(Model[i].Question)</label> 
       <input asp-for="@Model[i].Answer" /> 
      </td> 
     </tr>    
    } 
</table> 
<input type="submit" value="save" /> 

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

+0

Это работает, но это ошибка? Является ли это шагом назад, если я не ошибаюсь, я мог бы использовать foreach в более ранних версиях mvc? Также почему я не могу использовать ICollection, но я могу использовать IList или List, что такое diffrence? –

+0

Здесь ничего не изменилось. Вы можете использовать 'foreach' для простых типов, таких как' List 'или' List ', но если вы хотите редактировать сложные типы, вы должны использовать' for' aproach. Вы не можете использовать ICollection, потому что этот интерфейс не обеспечивает доступ к индексу. В основном вы можете использовать любой объект, который имеет что-то вроде этого 'T this [int index] {get; задавать; } ' – YuriyP

+0

Я вижу, спасибо, что разъяснил это для меня. –

0

документация here предполагают нет необходимости @ перед именем переменной. Вы также можете использовать явный вспомогательный тег аннотацию путем добавления th: к началу тега

@model ICollection<CustomModel> 
<form asp-action="Index" asp-controller="Home" method="POST"> 
    <table> 
     @foreach (var m in Model) 
     { 
      <tr> 
       <td><th:label asp-for="m.Answer">@m.Question</label><th:input asp-for="m.Answer"/></td> 
      </tr> 
     } 
    </table> 
    <input type="submit" value="save" /> 
</form> 
+0

Я пробовал с и без, теперь есть разница. –