2013-01-04 8 views
35

Say mam następujące modele:ASP.NET MVC 4 - do właściwości zbierania modelowych stanowisk pętli foreach, ale nie

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

public class Town 
{ 
    public string Name { get; set; } 
    public IEnumerable<Person> People { get; set; } 
} 

Wtedy, moim zdaniem Razor, mam to:

@model Town 
@using(Html.BeginForm()) 
{ 
    <table> 
     @foreach(var person in Model.People) 
     { 
      <tr> 
       <td>@Html.TextBoxFor(m => person.Name)</td> 
       <td>@Html.TextBoxFor(m => person.Age)</td> 
      </tr> 
     } 
    <table> 
    <input type="submit" /> 
} 

Wtedy, mam skargę o POST, coś takiego:

[HttpPost] 
public ActionResult Index(Town theTown) 
{ 
    //.... 
} 

Kiedy wysłać wiadomość, IEnumerable<Person> nie pochodzi przez. Jeśli patrzę na to w Skrzypek, zbieranie tylko posty raz, a nie wyliczać kolekcję, więc otrzymujemy:

People.Name = "whatever" 
People.Age = 99 

Jednak w przypadku zmiany osoby do IList i użyć pętli for zamiast foreach ...

@for(var i = 0;i < Model.People.Count;i++) 
{ 
    <tr> 
     <td>@Html.TextBoxFor(m => Model.People[i].Name)</td> 
     <td>@Html.TextBoxFor(m => Model.People[i].Age)</td> 
    </tr> 
} 

Działa. czy robię coś źle? czego mi brakuje?

+3

Jest to normalne zachowanie. Segregator modelu używa właściwości name elementów wejściowych ze zrenderowanego html. Używanie pętli for z indeksem jest jedynym sposobem na unikalne nazwy, które model wiążący może skojarzyć z modelem –

Odpowiedz

59

Problem nie jest związany z IEnumerable lub IList w taki sposób, w jaki renderujesz kolekcję w widoku.

@for(var i = 0;i < Model.People.Count;i++) 
{ 
    <tr> 
     <td>@Html.TextBoxFor(m => Model.People[i].Name)</td> 
     <td>@Html.TextBoxFor(m => Model.People[i].Age)</td> 
    </tr> 
} 

Zauważmy, że z każdego elementu listy jesteś dołączając stały wskaźnik, który umożliwia spoiwa modelu zrobić swoją magię

good read

+4

To nie zadziała w kolekcji Generic.niewielokrotne, więc będziesz musiał zmienić swoją kolekcję na jakąś formę kolekcji indeksowanej . – Eric

+0

Dzięki. Miło pomaga –

0

Wszystko czego brakowało umieszczenie var zamiast samego modelu (Ludzie), jak poniżej:

<table> 
@foreach(People person in Model.People) 
{ 
<tr> 
<td>@Html.TextBoxFor(m => person.Name)</td> 
<td>@Html.TextBoxFor(m => person.Age)</td> 
</tr> 
} 
<table> 
<input type="submit" /> 
+6

Nie będzie działać dla żądań postów, ponieważ deserializator json nie będzie mógł dopasować tych właściwości do pól. – Eric

+0

Działa, ale każdy formularz wejściowy ma tę samą nazwę i tę samą wartość. –

+0

@MuhammadAshikuzzaman Więc, jak możesz powiedzieć, że działa. – nam