Pregunta

En mi interfaz Tengo una lista de cuadros de texto, algo como esto: http://screencast.com/t/YjIxNjUyNmU

El número de cuadros de texto se desconoce como cada uno de ellos está asociado con una plantilla. En mi página, el objetivo es asociar un número a algunas de esas plantillas.

Aquí hay un ejemplo de código HTML:

<%  // loop on the templates
    foreach(ITemplate template in templates)
    {
        // get the content from the input dictionary
        int val;
        content.TryGetValue(template.Id, out val);
        // convert it as a string
        string value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name/id (for dictionary binding)
        string id = ??????????
        string name = ??????????????
%>
        <label for="<%= name %>"><%= template.Name %></label>
        <input type="text" id="<%= id %>" name="<%= name %>" value="<%= value %>" />
        <br />
<%  }
%>

Lo que espero, en mi controlador, es conseguir un IDictionary donde el primer int es el ID de plantilla, y el otro es el número dado por el usuario.

Esto es lo que quiero:

public ActionResult Save(int? id, Dictionary<int, int> countByTemplate)

He intentado muchas cosas pero nada funcionó. Traté de leer las fuentes pero es un laberinto, y yo estoy poniendo un headhache tratando de obtener información sobre el enlace de modelos.

Preguntas:

  • ¿hay una buena ressource sobre cómo funciona el modelbinding? Me gustaría calle detrás exhaustiva, estoy cansado de las 84093043 blogs que hablan de un ejemplo específico dado.
  • ¿cómo puedo construir mi HTML, utilizando para obtener un IDictionary (o incluso un IDictionary en la acción de mi controlador?

Muchas gracias por su ayuda

¿Fue útil?

Solución 2

Ok ... Gracias a Levi yo era capaz de conseguir una solución. No el más limpio, pero funciona.

El código HTML debe ser escrita de esta manera:

<%
int counter = 0;
// loop on the templates
foreach(ITemplate template in templates)
{
        // get the value as text
        int val;
        content.TryGetValue(template.Id, out val);
        var value = ((val > 0) ? val.ToString() : string.Empty);

        // compute the element name (for dictionary binding)
        string id = "cbts_{0}".FormatMe(template.Id);
        string dictKey = "cbts[{0}].Key".FormatMe(counter);
        string dictValue = "cbts[{0}].Value".FormatMe(counter++);
%>
        <input type="hidden" name="<%= dictKey %>" value="<%= template.Id %>" />
        <input type="text" id="<%= id %>" name="<%= dictValue %>" value="<%= value %>" />
        <label for="<%= id %>"><%= template.Name %></label>
        <br />
<%  }
%>

he tenido que añadir un campo oculto para almacenar el valor. Introduje un contador de 'falso' sólo para un bucle sobre el diccionario de la manera ASP.Net MVC quiere. Como resultado Tengo un diccionario lleno de mis valores y '0' cuando el cuadro de texto está vacía.

Otro problema apareció: la ModelState se consideró no válido debido a que "se requiere un valor". No quiero que mis valores a ser necesarios, pero mirando el código modelbinder, yo no encontraron una manera de contar el ligante que no se requiere un valor.

Así que engañó al ModelState en mi controlador, la eliminación de todos los errores, así:

public ActionResult Save(int? id, Dictionary<int, int> cbts)
{
    // clear all errors from the modelstate
    foreach(var value in this.ModelState.Values)
        value.Errors.Clear();

Bueno ... tengo una solución efectiva, pero el HTML es un poco feo ahora, y contrario a la intuición (utilizando un índice para recorrer una colección no indexada ??). Y necesito engañar cada vez que voy a utilizar este tipo de unión a tener todo el trabajo correctamente.

Así que ahora voy a abrir una nueva entrada para que el diccionario de ligante algo mejor. Aquí está: ASP.Net MVC 2 - ModelBinding mejor para Dictionary

Editar -. No es una solución más limpia, gracias a Pavel Chuchuva

En el código de controlador, utilice un int anulable como valor para el diccionario. Un código para añadir más, pero mucho más limpio mordió.

public ActionResult Save(int? id, Dictionary<int, int?> cbts)
{
    // this is our final dictionary<int, int>
    Dictionary<int, int> cbtsFinal = new Dictionary<int, int>();
    // loop on the dicitonary with nullable values
    foreach(var key in cbts.Keys)
    {
        // if we have a value
        if(cbts[key].HasValue)
            // then put it in the final dictionary
            cbtsFinal.Add(key, cbts[key].Value);
    }

Otros consejos

La información sobre cómo escribir sus elementos de entrada para la unión a matrices, diccionarios y otras colecciones se puede encontrar en http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx .

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