Pregunta

Supongamos que crea un formulario usando ASP.NET MVC que tiene un número dinámico de elementos de formulario.

Por ejemplo, necesita una casilla de verificación para cada producto, y la cantidad de productos cambia día a día.

¿Cómo manejaría los datos del formulario que se envían al controlador? No puede configurar parámetros en el método de acción porque no sabe cuántos valores de formulario volverán.

¿Fue útil?

Solución

Solo asigne un valor de nombre único a cada casilla de verificación:

<input class="approveCheck" id="<%= "approveCheck" + recordId %>" 
 name="<%= "approveCheck" + recordId %>" type="checkbox" />

Luego analice la lista de valores de formulario en la Acción, después de enviar:

foreach (var key in Request.Form.Keys)
    {
        string keyString = key.ToString();
        if (keyString.StartsWith("approveCheck", StringComparison.OrdinalIgnoreCase))
        {
            string recNum = keyString.Substring(12, keyString.Length - 12);

            string approvedKey = Request.Form["approveCheck" + recNum];
            bool approved = !String.IsNullOrEmpty(approvedKey);
            // ...

No necesita pasar valores de formulario como argumentos; puede obtenerlos de Request.Form.

Otra opción: escriba una carpeta de modelos para cambiar la lista a un tipo personalizado para el envío del formulario.

Otros consejos

Por la respuesta de Craig ... eso es más seguro. Hay peculiaridades para publicar varios elementos de formulario con el mismo nombre. Me gustaría agregar que sería prudente envolver la lógica que hace la " colección " de controles de forma similar a WebForms. Web Forms antepone el nombre del control del contenedor y agrega un índice. Por ejemplo, en un repetidor, los elementos del formulario dentro se llamarían (algo así como) RepeaterName_Element1, RepeaterName_Element2. Cuando vaya a sacar los elementos, debe usar FindControl o algo por el estilo.

Dependiendo de las carpetas que estés usando, esto debería funcionar:

<%var i = 0;
  foreach (var product (IList<ProductSelection>)ViewData["products"]) {%>
      <%=Html.Hidden(string.Format("products[{0}].Id", i), product.Id)%>
      <%=Html.Checkbox(string.Format("products[{0}].Selected", i))%>
      <%=product.Name%><br/>
<%}%>

... que dará como resultado algo así como HTML (observe la notación de matriz en los nombres):

<input name="products[0].Id" type="hidden" value="123">
<input name="products[0].Selected" type="checkbox">
Widget
<input name="products[1].Id" type="hidden" value="987">
<input name="products[1].Selected" type="checkbox">
Gadget

... y el método del controlador que maneja la publicación:

public ActionResult SelectProducts(IList<ProductSelection> products)
{
     ...
}

Al enlazarse, el parámetro products contendrá dos instancias de ProductSelection.

Una advertencia es que no he usado el nuevo enlace predeterminado para objetos complejos. Más bien estoy usando el NameValueDeserializer o CastleBind, ambos de MvcContrib. Ambos se comportan de esta manera. Supongo que el enlace en la Beta funcionará de la misma manera.

Dependiendo de sus datos, puede generar una 'Lista de verificación' (que ya no es posible en las versiones más recientes) y usar un parámetro string [] , o puede configurar múltiples formularios y simplemente modifique la acción.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top