2010-08-25 16 views
10

Sto cercando di associare un array dinamico di elementi di un modello di vista cui vi possono essere indici mancanti nel htmlarray vincolante con elementi mancanti in asp.net mvc

esempio con il modello vista

class FooViewModel 
{ 
    public List<BarViewModel> Bars { get; set; } 
} 

class BarViewModel 
{ 
    public string Something { get; set; } 
} 

e html

<input type="text" name="Bars[1].Something" value="a" /> 
<input type="text" name="Bars[3].Something" value="b" /> 
<input type="text" name="Bars[6].Something" value="c" /> 

momentaneamente, barre sarà solo essere nullo. come posso ottenere che il modello legatore ignori gli elementi mancanti? vale a dire quanto sopra si legherebbe a:

FooViewModel 
{ 
    Bars 
    { 
      BarViewModel { Something = "a" }, 
      BarViewModel { Something = "b" }, 
      BarViewModel { Something = "c" } 
    } 
} 

risposta

5

Aggiungi il .Index come prima input nascosto per gestire gli elementi fuori sequenza come spiegato in questo Phil Haacked blog post:

<input type="text" name="Bars.Index" value="" /> 
<input type="text" name="Bars[1].Something" value="a" /> 
<input type="text" name="Bars[3].Something" value="b" /> 
<input type="text" name="Bars[6].Something" value="c" /> 
+3

Molto vicino, ma la risposta accettata in questo url ha una soluzione più completa: http://stackoverflow.com/questions/8598214/mvc3-non-sequential-indices-and-defaultmodelbinder – Levitikon

+0

@Levitikon - La soluzione accettata nel tuo link è eccessivo. Non è necessario specificare un '.Index' per ogni elemento. Ho usato l'approccio di cui sopra numerose volte senza aver bisogno degli ingressi extra nascosti descritti nel tuo link. Inoltre, Phil Haack era nel team di sviluppo di ASP.NET MVC, quindi sono abbastanza sicuro di ciò che ha scritto nel suo blog. – amurra

+1

@amurra nell'articolo di Haack dice di usare un input nascosto separato per ogni campo, quindi sembrerebbe che sia necessario. – Mykroft

-1

non sapevo nemmeno che funzionasse!

tenendo questo in mente, id hanno fatto qualcosa di simile:

<input type="text" name="Bars.Something" value="a" /> 
<input type="hidden" name="Bars.Something" value="" /> 
<input type="text" name="Bars.Something" value="b" /> 
<input type="hidden" name="Bars.Something" value="" /> 
<input type="hidden" name="Bars.Something" value="" /> 
<input type="text" name="Bars.Something" value="c" /> 

che si spera inviare

a,,b,,,c 

ma ho il sospetto che legherà allo stesso modo come lei

Probabilmente avrai intenzione di scrivere un raccoglitore di modelli personalizzato che cerca l'indice massimo, crea un elenco di tali dimensioni quindi inserisce gli elementi nella posizione corretta.

Detto tutto questo, aspettare che qualcun altro per pubblicare un molto semplice attributo che si può mettere sulla vostra proprietà che lo fa solo lavoro; D

0

MVC è in grado di popolare lista stessa.

public ActionResult Index(FooViewModel model) 
{ 
    ... 

Quindi, non importa se manca qualcosa MVC creerà nuove List<BarViewModel> e per ogni indice trovati - [1], [3], [6] Si creerà nuova BarViewModel e aggiungerlo all'elenco. Quindi otterrai FooViewModel con barre popolate.

+0

Sì e no. Sembra che MVC interrompa la costruzione dell'array quando c'è una lacuna nella sequenza. – Levitikon

0

Una possibile soluzione potrebbe essere quella di istanziare il ViewModel e la collezione per il formato corretto (supponendo che è noto), poi aggiornarlo con TryUpdateModel ... qualcosa di simile:

[HttpPost] 
    public ActionResult SomePostBack(FormCollection form) 
    { 
     // you could either look in the formcollection to get this, or retrieve it from the users' settings etc. 
     int collectionSize = 6; 

     FooViewModel bars = new FooViewModel(); 
     bars.Bars = new List<BarViewModel>(collectionSize); 
     TryUpdateModel(bars, form.ToValueProvider()); 

     return View(bars); 
    }H 
Problemi correlati