Envío adecuado de formularios con controles autogenerados
-
05-07-2019 - |
Pregunta
Basado en: MVC Html.CheckBox y envío de formulario
Consideremos el siguiente ejemplo. Ver:
<% using(Html.BeginForm("Retrieve", "Home")) %>
<% { %>
<%foreach (var app in newApps) { %>
<tr>
<td><%=Html.CheckBox(""+app.ApplicationId )%></td>
</tr>
<%} %>
<input type"submit"/>
<% } %>
Controlador:
List<app>=newApps; //Database bind
for(int i=0; i<app.Count;i++)
{
var checkbox=Request.Form[""+app[i].ApplicationId];
if(checkbox!="false")// if not false then true,false is returned
}
La solución propuesta consistía en el análisis manual de Request.Form que me parece fuera del concepto MVC. Hace el problema mientras se prueba la unidad de este método de controlador. En este caso, necesito generar un objeto simulado Request.Form en lugar de algún ViewModel pasado como parámetro de entrada.
P: ¿Existe alguna otra solución para enviar formularios como este, de modo que el objeto ViewModel, que contiene la colección de controles enviados, se pase como parámetro de entrada al método del controlador?
Por ejemplo:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Retrieve(AppList[] applist)
o
public ActionResult Retrieve(AppList<App> applist)
etc.
Solución
Controlador:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Retrieve(AppList[] applist)
Ver:
<% using(Html.BeginForm("Retrieve", "Home")) %> { %>
<%foreach (var app in newApps) { %>
<tr>
<td><%=Html.CheckBox(String.Format("appList[{0}].AProperty", app.ApplicationId) %></td>
</tr>
<% } %>
<input type"submit" />
<% } %>
UPDATED:
Si ApplicationId es una clave de DB, es mejor usar AppList<App>
como parámetro de acción. Entonces su formulario se vería como:
<% using(Html.BeginForm("Retrieve", "Home")) %> { %>
<% var counter = 0; %>
<% foreach (var app in newApps) { %>
<tr>
<td><%=Html.CheckBox(String.Format("appList[{0}].Key", counter), app.ApplicationId) %></td>
<!-- ... -->
<td><%=Html.Input(String.Format("appList[{0}].Value.SomeProperty1", counter), app.SomeProperty1) %></td>
<td><%=Html.Input(String.Format("appList[{0}].Value.SomePropertyN", counter), app.SomePropertyN) %></td>
<% counter = counter + 1; %>
</tr>
<% } %>
<input type"submit" />
<% } %>