2009-06-23 24 views
11

Estoy tratando de modelar un conjunto de casillas de verificación generadas dinámicamente para procesarlas en la acción del controlador pero no puedo obtener el enlace del modelo a ocurrir. Este es el escenario:ASP.NET MVC - Modelo vinculando un conjunto de casillas de verificación generadas dinámicamente - cómo

Mi clase ViewModel (DocumentAddEditModel) contiene un diccionario (Diccionario < cadena, bool>) con la cadena de cada entrada es el nombre/etiqueta para cada casilla de verificación y el booleano que indica si está marcada la casilla de verificación:

public class DocumentAddEditModel 
    { 
     ... 
     private Dictionary<string, bool> _categoryCheckboxes = new Dictionary<string,bool>(); 
     ... 

     ... 
     public Dictionary<string, bool> CategoryCheckboxes 
     { 
      get { return _categoryCheckboxes; } 
      set { _categoryCheckboxes = value; } 
     } 
     ... 
    } 
} 

Dentro de mi controlador de la acción que se encarga de la solicitud GET para la forma rellena la Dictonary de la siguiente manera:

public class DocumentsController : Controller 
{ 
    [RequiresAuthentication] 
    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult Add() 
    { 
     DocumentAddEditModel documentAddEditModel = new DocumentAddEditModel(); 
     ... 
     Dictionary<string, bool> categoryCheckboxes = new Dictionary<string, bool>(); 
     ... 
     string[] categories = Enum.GetNames(typeof(Category)); 

     foreach (string category in categories) 
      categoryCheckboxes.Add(category, false); 

     documentAddEditModel.CategoryCheckboxes = categoryCheckboxes; 

     return View(documentAddEditModel); 
    } 
} 

Dentro de la vista tengo el siguiente para generar las casillas de verificación:

<% foreach (KeyValuePair<string, bool> categoryCheckbox in ViewData.Model.CategoryCheckboxes) 
    {%> 
    <input class="checkbox" type="checkbox" name="CategoryCheckboxes[0].Key" id="<%= categoryCheckbox.Key %>" /> 
    <label class="categoryLabel" for="<%= categoryCheckbox.Key %>"><%= categoryCheckbox.Key %></label> 
<% } %> 

pero creo que aquí es donde debe estar el problema. No estoy seguro de lo que necesita ir en el atributo de nombre. El problema es que una vez enviado de vuelta a la siguiente método de acción en el DocumentsController:

[RequiresAuthentication] 
[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Add(DocumentAddEditModel documentAddEditModel) 
{ 
    ... 
} 

documentAddEdit.Model.CategoryCheckboxes siempre es nula. ¿Cómo configuro esto para que el diccionario CategoryCheckboxes se llene correctamente con el nombre y el valor de bool marcado/no marcado para las casillas de verificación?

Gracias

Respuesta

10

Si va a enlazar sus casillas a un Dictionary<string, bool> intente esto:

<% var i = 0; %> 
<% foreach (KeyValuePair<string, bool> categoryCheckbox in Model.CategoryCheckboxes) {%> 

    <input type="hidden" name="<%= String.Format("CategoryCheckboxes[{0}].Key", i) %>" value="<%= categoryCheckbox.Key %>" /> 
    <%= Html.CheckBox(String.Format("CategoryCheckboxes[{0}].Value", i), categoryCheckbox.Value) %> 

    <label class="categoryLabel" for="<%= categoryCheckbox.Key %>"><%= categoryCheckbox.Key %></label> 

    <% i++; %> 
<% } %> 

Esperanza esto ayuda

Actualizado:

Para la unión a IDictionary<T1, T2> su forma obligada contiene entradas con "CategoryCheckboxes [n] .Key" y "CategoryCheckbo" xes [n] .Value "Id/Nombres, donde n debe estar basado en cero e ininterrumpido.

+0

Gracias eu-ge-ne, que parece hacer el aunque, ¿podrías aclarar qué está pasando aquí? Entiendo que dado que el control de casilla de verificación ( Matthew

+0

Nuevamente me di cuenta de que el Html.CheckBox() htmlhelper genera un segundo campo oculto con un atributo de nombre igual al de la casilla de verificación visible pero cuando comparo el html generado para una casilla cuando no está marcada: – Matthew

+0

Matthew

1

Los elementos ocultos son el modus operandi de asp.net. en la versión de formularios web era el ViewState, que era un campo oculto masivo, en el MVC sus campos ocultos más ligeros y más directos por control. No estoy seguro de lo que está mal o inquietante sobre eso. De alguna manera tiene que mantener el estado, puede hacerlo desde el lado del cliente o del servidor. Sugiero lado del cliente para la información no sensible de esa manera todavía estará allí si el servidor se reinicia entre las devoluciones de datos, etc. Algo

0

más simple:

@foreach (var pair in Model.CategoryCheckboxes) 
{ 
    @Html.CheckBoxFor(m=>m.CategoryCheckboxes[pair.Key]) 
} 
Cuestiones relacionadas