2016-05-27 20 views
5

Sto cercando di creare una forma molto semplice di inviare indietro alcuni valori da una collezione di modelliModelBinding sulla raccolta modello

Quando i clic su Invia, e guardo la collezione tornato non contiene alcun oggetto. Vedo anche che l'asp-for non genera l'indice di raccolta che mi aspettavo.

Ho un modello semplice

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

E questo è il mio punto di vista

@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" /> 

Esempio di come questo possa sembrare quando la pagina è 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> 

Questo è stato io Supponendo che avrebbe un indice, ma sembra che tratti ogni riga come un modello induvidal invece di una collezione di modelli.

Cosa sto facendo di sbagliato qui? È un bug o di progettazione?

progetto di test Github https://github.com/lasrol/TestModelBindingList

risposta

4

Cambia il tuo modello di @model List<CustomModel> E che usare approccio prossimo

<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" /> 

Quindi, come si può vedere che dovresti accedere agli elementi della lista tramite indice per rendere correttamente l'attributo nome per gli input. Inoltre, non dimenticare di includere altre proprietà dell'oggetto tramite input nascosti, altrimenti i valori verranno rilasciati in post azione.

+0

Funziona, ma è un bug? È un passo indietro, se non sbaglio, potrei usare foreach nelle precedenti versioni di mvc? Anche perché non posso usare un ICollection, ma posso usare un IList o List, qual è la diffrence? –

+0

Qui non è cambiato nulla rispetto alla versione precedente. Si può usare 'foreach' per tipi semplici come' Lista 'o' Lista 'ma se si desidera modificare tipi complessi si dovrebbe usare" for' aproach. Non è possibile utilizzare ICollection perché questa interfaccia non fornisce accesso all'indice. Fondamentalmente puoi usare qualsiasi oggetto che abbia qualcosa di simile a questo 'T questo [int index] {get; impostato; } ' – YuriyP

+0

Vedo, grazie per aver chiarito questo per me. –

0

La documentazione here suggeriscono non v'è alcuna necessità di @ prima del nome della variabile. È inoltre possibile utilizzare esplicita annotazione tag aiutante aggiungendo th: all'inizio del tag

@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

Ho provato con e senza, ora c'è differenza. –