2009-06-24 35 views

Respuesta

7

Parece que está teniendo el mismo problema general que el serializador DataContract original, en lo que respecta a las referencias cíclicas. Mientras que los objetos que hacen referencia entre sí son bastante comunes con los gráficos de objetos en la memoria, tales referencias cíclicas inevitablemente dan lugar a infinitas recursiones cuando se serializan si el serializador no las tiene en cuenta específicamente. Existen pocos estándares establecidos para tratar con referencias cíclicas en los formatos comunes de serialización no binarios (XML y JSON son los dos más prevalentes).

Microsoft resolvió el problema cíclico para el serializador DataContract en .NET 3.5 SP1 haciendo uso de la ref semántica en xml. Que yo sepa, no existe tal cosa para JSON, que podría ser la razón por la cual JSON.NET le impide serializar su gráfico de objetos.

Me aseguraré de que solo tenga referencias en su gráfico de objeto que sean navegables en un solo sentido, en lugar de en ambos sentidos (es decir, solo de padre a hijo, no de hijo a padre). Esos padres/hijos e hijos/padres son los tipos más comunes de referencias cíclicas. También es posible que un hijo de nivel inferior haga referencia a la raíz del gráfico, lo que hace que se cree un gráfico cíclico indirecto (aunque estos tienden a ser menos comunes que los bucles padre/hijo)

Una vez elimina cualquier referencia cíclica en su gráfico de objetos, debería poder serializar.

+0

Gracias por su respuesta. No quería eliminar ninguna referencia cíclica en el gráfico de objetos, ya que no estoy del todo seguro de cómo hacerlo y cuáles serían las implicaciones de realizar este cambio. En su lugar, creé objetos sencillos y llenaron estos objetos utilizando objetos Entity Framework y luego serializar los objetos simples y funciona bien. – Hitesh

+4

En general, es una buena práctica mantener sus entidades de dominio y sus DTO independientes entre sí. Las entidades en su estado gráfico rico e nativo son una gran manera de modelar un dominio de problema de negocio y resolver problemas de negocios, pero no se prestan bien a la orientación de servicio y serialización. Mi preferencia personal es mantener mi dominio tan rico e interrelacionado como sea posible para modelar el negocio y proporcionar API de servicio independiente que proporcionen DTO serializables individuales. – jrista

+0

Este problema es más grande que solo los ciclos en las referencias causadas por las propiedades de navegación bidireccional. ¿Qué pasa cuando tienes 10 objetos que hacen referencia al mismo objeto dependiente exacto? ¿Cuál es la forma estándar de serializar este gráfico sin duplicar el objeto referenciado 10 veces? ¿Y por esta misma señal, deserializar los datos correctamente en el lado del cliente, recreando una sola instancia del objeto referenciado en lugar de 10 diferentes? ¿Algún estándar o patrón común para esto usando JSON? – Marchy

4

Tuve este problema y lo resolví añadiendo el Newtonsoft.Json.JsonIgnoreAttribute a la propiedad que causaba el bucle. Obviamente, esa propiedad no se serializará. Para ayudar con este problema, normalmente tendré tanto la identificación de referencia extranjera como la clase extranjera en mis entidades. Me doy cuenta de que esto no es intuitivo (o súper genial OO), pero es el camino recomendado por Julia Lerman en su libro Programming Entity Framework: Code First. Descubrí que ayuda a solucionar varios problemas con Entity Framework.

public class SomeEntity 
{ 
     [JsonIgnore] 
     public ForeignEntity SomeForeignEntity {get;set;} 
     public Guid ForeignEntityId {get;set;} 
} 

Actualización: Me olvidó mencionar también que necesitaba para desactivar servidores proxy en el DbContext así:

dataContext.Configuration.ProxyCreationEnabled = false; 

Si va a escribir el código de un servicio (que parece probable que si usted está serializando) , entonces esto probablemente no sea un problema, pero hay algunas cosas que pierde cuando la creación del proxy está deshabilitada. Vea aquí: http://www.sellsbrothers.com/posts/Details/12665 para más detalles.

estoy usando el API de Web MS, por lo que sólo desactivar la creación del proxy cuando construyo mi controlador:

public class MailingApiController : ApiController 
{ 
    public MailingApiController() 
    { 
     PreventDeepSerialization(); 
    } 

    private static void PreventDeepSerialization() 
    { 
     var dataContext = Injector.Get<IIntertwyneDbContext>(); 
     dataContext.Configuration.ProxyCreationEnabled = false; 
    } 
     .... 
1

Para evitar esto Convertí mis Entidades de Primera Código basado POCO. Para hacer esto, haga clic derecho dentro de su ventana de edmx y seleccione:

Agregue el elemento de generación de código> pestaña Código> EF POCO Entity Generator.

Tenga en cuenta que puede necesitar instalarlo con nuget si no lo ve.

En tiempo de ejecución, sin embargo, EF agrega clases de proxy a esos objetos con fines de seguimiento, pero tienden a hacer un lío con el proceso de serialización. Para evitar esto podemos simplemente establecer ProxyCreationEnabled en false de la siguiente manera:

var context = new YourEntities(); 
context.Configuration.ProxyCreationEnabled = false; 

var results = context.YourEntity.Take(100).ToList(); 

A continuación, puede volver con seguridad JSON.NET datos serializados omitiendo la referencia por defecto bucle de la siguiente manera:

return JsonConvert.SerializeObject(results, Formatting.Indented, 
    new jsonSerializerSettings { 
     ReferenceLoopHandling = ReferenceLoopHandling.Ignore 
    }); 
Cuestiones relacionadas