Saltar al contenido

Error de JSON.NET Bucle de autorreferencia detectado para el tipo

Te damos el resultado a esta traba, al menos eso deseamos. Si presentas interrogantes dínoslo y sin dudas

Solución:

Solución 1: ignorar la referencia circular globalmente

(He elegido/probado este, como muchos otros)

El serializador json.net tiene una opción para ignorar las referencias circulares. Pon el siguiente código en WebApiConfig.cs expediente:

 config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling 
= Newtonsoft.Json.ReferenceLoopHandling.Ignore; 

La solución simple hará que el serializador ignore la referencia, lo que provocará un bucle. Sin embargo, tiene limitaciones:

  • Los datos pierden la información de referencia de bucle
  • La solución solo se aplica a JSON.net
  • El nivel de referencias no se puede controlar si hay una cadena de referencia profunda

Si desea utilizar esta solución en un proyecto ASP.NET que no sea API, puede agregar la línea anterior a Global.asax.cspero primero agrega:

var config = GlobalConfiguration.Configuration;

Si quieres usar esto en Núcleo .Net proyecto, puedes cambiar Startup.cs como:

  var mvc = services.AddMvc(options =>
        
           ...
        )
        .AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);

Arreglo 2: Preservar la referencia circular globalmente

Esta segunda solución es similar a la primera. Solo cambia el código a:

config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling 
     = Newtonsoft.Json.ReferenceLoopHandling.Serialize;     
config.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling 
     = Newtonsoft.Json.PreserveReferencesHandling.Objects;

La forma de los datos cambiará después de aplicar esta configuración.

[
   
      "$id":"1",
      "Category":
         "$id":"2",
         "Products":[
            
               "$id":"3",
               "Category":
                  "$ref":"2"
               ,
               "Id":2,
               "Name":"Yogurt"
            ,
            
               "$ref":"1"
            
         ],
         "Id":1,
         "Name":"Diary"
      ,
      "Id":1,
      "Name":"Whole Milk"
   ,
   
      "$ref":"3"
   
]

$id y $ref mantienen todas las referencias y hacen que el nivel del gráfico del objeto sea plano, pero el código del cliente necesita conocer el cambio de forma para consumir los datos y solo se aplica al serializador JSON.NET también.

Solución 3: ignorar y conservar la referencia attributes

Esta solución es decorar. attributes en la clase de modelo para controlar el comportamiento de serialización en el nivel de modelo o propiedad. Para ignorar la propiedad:

 public class Category 
     
        public int Id  get; set;  
        public string Name  get; set;  
       
        [JsonIgnore] 
        [IgnoreDataMember] 
        public virtual ICollection Products  get; set;  
     

JsonIgnore es para JSON.NET e IgnoreDataMember es para XmlDCSerializer. Para preservar la referencia:

 // Fix 3 
        [JsonObject(IsReference = true)] 
        public class Category 
         
            public int Id  get; set;  
            public string Name  get; set;  
         
           // Fix 3 
           //[JsonIgnore] 
           //[IgnoreDataMember] 
           public virtual ICollection Products  get; set;  
        
        
       [DataContract(IsReference = true)] 
       public class Product 
        
           [Key] 
           public int Id  get; set;  
        
           [DataMember] 
           public string Name  get; set;  
        
           [DataMember] 
           public virtual Category Category  get; set;  
       

JsonObject(IsReference = true)] es para JSON.NET y [DataContract(IsReference = true)] es para XmlDCSerializer. Tenga en cuenta que: después de aplicar DataContract en clase, necesitas agregar DataMember a las propiedades que desea serializar.

los attributes se puede aplicar tanto en el serializador json como en el xml y brinda más controles en la clase del modelo.

Usar JsonSerializerSettings

  • ReferenceLoopHandling.Error (predeterminado) generará un error si se encuentra un bucle de referencia. Es por eso que obtienes una excepción.
  • ReferenceLoopHandling.Serialize es útil si los objetos están anidados pero no indefinidamente.
  • ReferenceLoopHandling.Ignore no serializará un objeto si es un objeto secundario de sí mismo.

Ejemplo:

JsonConvert.SerializeObject(YourPOCOHere, Formatting.Indented, 
new JsonSerializerSettings 
 
        ReferenceLoopHandling = ReferenceLoopHandling.Serialize
);

Si tiene que serializar un objeto anidado indefinidamente, puede usar PreserveObjectReferences para evitar una StackOverflowException.

Ejemplo:

JsonConvert.SerializeObject(YourPOCOHere, Formatting.Indented, 
new JsonSerializerSettings 
 
        PreserveReferencesHandling = PreserveReferencesHandling.Objects
);

Elija lo que tenga sentido para el objeto que está serializando.

Referencia http://james.newtonking.com/json/help/

La solución es ignorar las referencias de bucle y no serializarlas. Este comportamiento se especifica en JsonSerializerSettings.

Único JsonConvert con una sobrecarga:

JsonConvert.SerializeObject(YourObject, Formatting.Indented,
    new JsonSerializerSettings() 
        ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    
);

Configuración global con código en Application_Start() en Global.asax.cs:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings 
     Formatting = Newtonsoft.Json.Formatting.Indented,
     ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
;

Referencia: https://github.com/JamesNK/Newtonsoft.Json/issues/78

Comentarios y valoraciones del post

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *