2010-11-03 17 views
5

Estoy usando ASP.NET MVC y estoy tratando de generar una pieza de Javascript como parte de la representación de la vista. Tengo un modelo que expone una matriz de tipos simples y me gustaría generar una matriz equivalente de JavaScript/json en la vista para que pueda actuar sobre ella usando jQuery. Así que dado el siguiente modelo:Generar una matriz JSON sin procesar en ASP.NET MVC

public class Info { 
    public string Name {get;set;} 
    public int ID {get; set;} 
} 

public class InfoModel{ 
    public Info[] InfoList {get;set;} 
} 

... Querría para generar una matriz de JavaScript con este aspecto:

var infoList = [ 
     { 
     Name = "...", 
     ID = 1 
     } , 
     { 
     Name = "...", 
     ID = 2 
     }, 
     .... 
     { 
     Name = "...", 
     ID = N 
     }]; 

¿Hay una manera agradable y concisa de hacer esto en la vista, Parece que tengo problemas con la codificación de las comillas si intento que el modelo genere una representación json, por lo que actualmente solo puedo generarlo utilizando un código de espaghetti/asp clásico que preferiría haber reemplazado por un buen trazador de líneas.

EDITAR: Tenga en cuenta que no estoy buscando que un controlador devuelva un JsonResult, quiero que mi vista contenga una matriz de javascript que se genera desde mi modelo en una sola línea de código (si es posible))

EDIT: Llegué a una parte del camino, pero parece estar luchando con la codificación. Este código en la vista:

<script> 
var list = <%: HtmlExtension.ToJson(Model.InfoList) %>; 
</script> 

(donde toJSON encapsula la conversión a cadena mediante JavaScriptSerializer) da salida a algunos fallos de codificación:

var info = [{&quot;Name&quot;:&quot;Low End&quot;,&quot;ID&quot;:1}]; 

..which no es lo que estaba buscando. Podría hacer esto:

var info = <% Response.Write(HtmlExtension.ToJson(Model.InfoList)); %>; 

que funciona, pero no se ve tan brillante. ¿Debo ignorar explícitamente la codificación como se muestra (La salida es sensata, no generada por el usuario, por lo que puede no ser un problema) o me falta algo más que la hace menos clásica?

Respuesta

5

Parece que tiene un problema de codificación. Creo que usted tiene dos opciones aquí:

  1. Al crear su extensión, asegúrese de que vuelva MvcHtmlString en lugar de una normal de string, o ...
  2. En lugar de utilizar el estilo <%: ... %> para escribir su código , use <%= ... %> para no hacer la codificación.
+0

¡SÍ! gracias Jonathan, el MvcHtmlString fue la magia que estaba esperando ... –

+0

Pude utilizar esta línea de código en mi archivo HTML de afeitar: MvcHtmlString.Create (Json.Encode (Modelo)) – bkwdesign

+0

Exactamente. Al final es 'MvcHtmlString' la clave. –

1

Sí hay una manera agradable:

InfoModel viewModel; // get this from wherever 
return Json(viewModel); 

MVC traducirá la colección a la JSON relevante.

Esto devolverá un JsonResult (es decir, JSON sin formato).

¿Eso es lo que buscas?

Si quería hacer algo como esto en su Vista:

<script type="text/javascript> 
    var json = <%: Model.JsonStuff %> 
    // more js 
</script> 

Entonces ejemplo anterior no funcionará.

Tendrás que serializarlo manualmente cuando construyas tu ViewModel.

EDITAR

Aquí hay un ejemplo de cómo se puede serializar sus datos.

JavaScriptSerializer js = new JavaScriptSerializer(); 
var listOfInfos; // this will be a collection (e.g List) of Infos. 
var viewModel = new InfoModel 
       { 
        InfoList = js.Serialize(listOfInfos); 
       }; 
return View(viewModel); 

Mientras de listOfInfo implementa IEnumerable, se colocarán en serie a una matriz JSON.

Puede que tenga que jugar un poco con su modelo de vista, pero eso debería ponerlo en el camino correcto.

+0

Estoy buscando la segunda opción, haciendo json en la vista, sin tener una acción de controlador return json. Actualizaré la pregunta para aclarar. –

+0

@soren enemaerke - mira mi actualización. – RPM1984

+0

Gracias por el seguimiento, probé su enfoque y no funcionó del todo. Por favor, vea mi pregunta actualizada (ToJson encapsula la llamada js.Serialize para mantenerlo fuera del viewmodel) –

Cuestiones relacionadas