2010-08-25 10 views
10

Estoy intentando unirse a una matriz dinámica de elementos a un modelo de vista donde podría haber índices que falta en el htmlarrays de unión con elementos que faltan en mvc asp.net

por ejemplo con el modelo de vista

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

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

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

por el momento, las barras sólo será nulo. ¿Cómo podría obtener la carpeta de modelo para ignorar los elementos que faltan? es decir, lo anterior se uniría a:

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

Respuesta

5

Añadir la .Index como su primera entrada oculta para tratar con elementos fuera de secuencia como se explica en este Phil Hacked blog publicación:

<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

Muy cerca, pero la respuesta aceptada en esta url tiene una solución más completa: http://stackoverflow.com/questions/8598214/mvc3-non-sequential-indices-and-defaultmodelbinder – Levitikon

+0

@Levitikon - La solución aceptada en su enlace es exagerado No necesita especificar un '.Index' para cada elemento. He utilizado el enfoque anterior en numerosas ocasiones sin necesidad de las entradas ocultas adicionales que se describen en su enlace. Además, Phil Haack estaba en el equipo de desarrollo ASP.NET MVC, así que estoy bastante seguro de que lo que escribió en su blog es el camino a seguir. – amurra

+1

@amurra en el artículo de Haack dice que use una entrada oculta por separado para cada campo, por lo que parece que es necesario. – Mykroft

-1

¡Ni siquiera sabía que funcionó!

teniendo esto en cuenta, ID haber hecho algo como:

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

la que se espera pueda publicar

a,,b,,,c 

pero sospecho que se unirán en la misma manera que usted describe

Probablemente va a tener que escribir un encuadernador de modelo personalizado que busque el índice máximo, haga una lista de ese tamaño y luego coloque los elementos en el lugar correcto.

decir todo eso, esperar a que alguien más para publicar un atributo muy simple que se puede poner en su propiedad que lo hace sólo el trabajo; D

0

MVC es capaz de rellenar la lista en sí.

public ActionResult Index(FooViewModel model) 
{ 
    ... 

Así que no importa si falta algo MVC crear nuevos List<BarViewModel> y para cada índice encontrado - [1], [3], [6] que creará nuevas BarViewModel y añadirlo a la lista. Entonces obtendrás FooViewModel con Barras pobladas.

+0

Sí y no. Parece que MVC deja de construir la matriz cuando hay un espacio en la secuencia. – Levitikon

0

Una posible solución podría ser crear una instancia del modelo de vista y la colección al tamaño correcto (asumiendo que es conocido), y luego actualizarlo con TryUpdateModel ... algo así como:

[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 
Cuestiones relacionadas