En el trabajo cotidiano estaba armando un servicio WCF que genera JSON a partir de entidades de Entity Framework, cuando la simplicidad me genero un error. Simplicidad porque no quería mas que un listado de una de mis entidades en formato JSON
Estaba utilizando DataContractJsonSerializer como siempre en mis app web, pero parece que tiene un problema con EF 1.0:
Como bien dice “reza” este articulo: Serializing Entity Framework object to JSON
“…serializing EF object to JSON is not quite of an easy task…”
Lo bueno que encontré la solución utilizando la librería JSON.NET
Json.NET library makes working with JSON formatted data in .NET simple. Key features include a flexible JSON serializer to for quickly converting .NET classes to JSON and back again, and LINQ to JSON for reading and writing JSON.
Mensaje de Horror Error:
[EN]
"The type ‘EntidadXXX’ cannot be serialized to JSON because its IsReference setting is ‘True’. The JSON format does not support references because there is no standardized format for representing references. To enable serialization, disable the IsReference setting on the type or an appropriate parent class of the type."
[ES]
"El tipo ‘EntidadXXX’ no se puede serializar a JSON porque su valor IsReference es ‘True’. El formato JSON no admite referencias porque no hay un formato estandarizado para representarlas. Para habilitar la serialización, deshabilite el valor IsReference en el tipo o en una clase primaria apropiada del tipo."
Aquí va el ejemplo
El código que genera la excepción antes mencionada
public string ListadoJSON(){ string cadenaJSON = string.Empty; ItemRepository itemRepositorio = new ItemRepository(); Int32 paginaPageTotal; List<Item> listado = itemRepositorio.Buscar("", 0, 0, 17, 10, 1, out paginaPageTotal); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<Item>)); using (MemoryStream ms = new MemoryStream()) { ser.WriteObject(ms, listado); cadenaJSON = Encoding.Default.GetString(ms.ToArray()); } return cadenaJSON; }
Esto genera un error al momento de serializar
OPCION 1:Crear un listado para serializar con objetos anónimos
Como no puede serializar la entidad entonces generamos un nuevo listado con las propiedades que queremos serializar
ArrayList listadoItemsParaSerializar = new ArrayList(); foreach (var item in listado) { var itemNuevo = new { id = item.ItemId, nombre=item.Nombre}; listadoItemsParaSerializar.Add(itemNuevo); }
Y luego serializamos con DataContractJsonSerializer el nuevo listado: listadoItemsParaSerializar 😉
OPCION 2: sin crear nada utilizando la librería JSON.NET
Utilizando JSON.NET solucionando el problema
public string ListadoJSONConJSONDotNET(){ string cadenaJSON = string.Empty; ItemRepository itemRepositorio = new ItemRepository(); Int32 paginaPageTotal; List<Item> listado = itemRepositorio.Buscar("", 0, 0, 17, 10, 1, out paginaPageTotal); cadenaJSON = Newtonsoft.Json.JsonConvert.SerializeObject(listado, Newtonsoft.Json.Formatting.Indented); return cadenaJSON; }
Es la forma mas simple, pero la librería tiene varios convertidores, me gusto del Datatable que tengo por ahí algunos para consultas “cuadradas” para reportes o gráficos y el de JavaScriptDateTimeConverter . Mas info en la ayuda online
Espero que les sirva de ayuda o guía.
Enlaces
- JSON.NET
http://www.codeplex.com/Json- Ayuda online de JSON.NET
http://james.newtonking.com/projects/json/help/ - Blog:
http://james.newtonking.com/
- Ayuda online de JSON.NET
- JSON