JSON.NET Error Auto referenciado bucle detectado para tipo


Intenté serializar la clase POCO que se generaba automáticamente a partir del Modelo de Datos de Entidad .edmx y cuando usé

JsonConvert.SerializeObject 

Tengo el siguiente error:

Bucle de auto referencia de error detectado para el sistema de tipo.datos.entidad se produce .

¿Cómo resuelvo este problema?

Author: Kahbazi, 2011-09-13

17 answers

Esa fue la mejor solución https://code.msdn.microsoft.com/Loop-Reference-handling-in-caaffaf7

Solución 1: Ignorar la referencia circular globalmente

(He elegido / probado este, como muchos otros)

El json.net serializer tiene una opción para ignorar las referencias circulares. Ponga el siguiente código en el archivo WebApiConfig.cs:

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

La solución simple hará que serializer ignore la referencia que causará un bucle. Sin embargo, ha limitaciones:

Los datos pierden la información de referencia del bucle La correcció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 corrección en una no api ASP.NET proyecto, puede agregar la línea anterior a Global.asax.cs, pero primero agregue:

var config = GlobalConfiguration.Configuration;

Si desea usar esto en el proyecto . Net Core, puede cambiar Startup.cs como:

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

Solución 2: Preservar la referencia circular globalmente

Esto la segunda corrección es similar a la primera. Simplemente cambie 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 datos se 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"
   }
]

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

Solución 3: Ignorar y conservar atributos de referencia

Esta corrección es decorar atributos en la clase modelo para controle el comportamiento de serialización a 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<Product> Products { get; set; } 
    } 

JsonIgnore es para JSON.NET y 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<Product> 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 la clase, debe agregar DataMember a las propiedades que desea serializar.

Los atributos se pueden aplicar tanto en serializer json como xml y proporciona más controles en el modelo clase.

 302
Author: Bishoy Hanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-10-02 09:49:39

Use JsonSerializerSettings

  • ReferenceLoopHandling.Error (predeterminado) se producirá un error si se encuentra un bucle de referencia. Esta es la razón por la que se obtiene 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 hijo en sí mismo.

Ejemplo:

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

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

Ejemplo:

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

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

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

 388
Author: DalSoft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-13 11:18:39

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

Soltero 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

 39
Author: smockle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-16 16:34:07

La forma más sencilla de hacerlo es instalar Json.NET desde nuget y añadir el atributo [JsonIgnore] a la propiedad virtual de la clase, por ejemplo:

    public string Name { get; set; }
    public string Description { get; set; }
    public Nullable<int> Project_ID { get; set; }

    [JsonIgnore]
    public virtual Project Project { get; set; }

Aunque en estos días, creo un modelo con solo las propiedades que quiero pasar por lo que es más ligero, no incluye colecciones no deseadas, y no pierdo mis cambios cuando reconstruyo los archivos generados...

 30
Author: Sam Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-13 09:29:01

En.NET Core 1.0, puede establecer esto como una configuración global en su inicio.archivo cs:

using System.Buffers;
using Microsoft.AspNetCore.Mvc.Formatters;
using Newtonsoft.Json;

// beginning of Startup class

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(options =>
        {
            options.OutputFormatters.Clear();
            options.OutputFormatters.Add(new JsonOutputFormatter(new JsonSerializerSettings(){
                ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
            }, ArrayPool<char>.Shared));
        });
    }
 20
Author: Caleb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-14 18:49:17

Podemos agregar estas dos líneas en DbContext class constructor para deshabilitar el bucle de Auto-referencia, como

public TestContext()
        : base("name=TestContext")
{
    this.Configuration.LazyLoadingEnabled = false;
    this.Configuration.ProxyCreationEnabled = false;
}
 6
Author: Sanjay Nishad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-25 14:49:13

También puede aplicar un atributo a la propiedad. El atributo [JsonProperty( ReferenceLoopHandling = ... )] es muy adecuado para esto.

Por ejemplo:

/// <summary>
/// Represents the exception information of an event
/// </summary>
public class ExceptionInfo
{
    // ...code omitted for brevity...

    /// <summary>
    /// An inner (nested) error.
    /// </summary>
    [JsonProperty( ReferenceLoopHandling = ReferenceLoopHandling.Ignore, IsReference = true )]
    public ExceptionInfo Inner { get; set; }

    // ...code omitted for brevity...    
}

Esperanza que ayuda, Jaans

 4
Author: Jaans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-10 13:11:11

Para ignorar las referencias de bucle y no serializarlas globalmente en MVC 6 use lo siguiente en startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().Configure<MvcOptions>(options =>
        {
            options.OutputFormatters.RemoveTypesOf<JsonOutputFormatter>();
            var jsonOutputFormatter = new JsonOutputFormatter();
            jsonOutputFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            options.OutputFormatters.Insert(0, jsonOutputFormatter);
        });
    }
 3
Author: GerardBeckerleg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-16 13:53:22

Use esto en WebApiConfig.cs clase:

var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
 2
Author: Anand Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-02 08:15:19

Para mí tuve que ir por un camino diferente. En lugar de tratar de arreglar el JSON.Net serializador Tuve que ir después de la carga perezosa en mi datacontext.

Acabo de añadir esto a mi repositorio base:

context.Configuration.ProxyCreationEnabled = false;

El objeto "context" es un parámetro constructor que uso en mi repositorio base porque uso inyección de dependencias. Puede cambiar la propiedad ProxyCreationEnabled en cualquier lugar donde cree una instancia de su datacontext en su lugar.

Http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html

 2
Author: Xipooo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-18 20:21:24

Para serializar usin NEWTONSOFTJSON cuando tiene un problema de bucle, en mi caso no necesitaba modificar global.asax o apiconfig. Solo uso JsonSerializesSettings ignorando el manejo de bucles.

JsonSerializerSettings jss = new JsonSerializerSettings();
jss.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
var lst = db.shCards.Where(m => m.CardID == id).ToList();
string json = JsonConvert.SerializeObject(lst, jss);
 2
Author: Carlos Barini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-22 20:07:49

Tuve esta excepción y mi solución de trabajo es Fácil y Simple,

Ignore la propiedad Referenciada agregándole el atributo JsonIgnore:

[JsonIgnore]
public MyClass currentClass { get; set; }

Restablecer la propiedad al Deserializar es:

Source = JsonConvert.DeserializeObject<MyObject>(JsonTxt);
foreach (var item in Source)
        {
            Source.MyClass = item;
        }

Usando Newtonsoft.Json;

 2
Author: Mayer Sariggs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-09 18:06:27

Si está utilizando.NET Core 2.0, actualice la sección ConfigureServices en Inicio.cs

Https://docs.microsoft.com/en-us/ef/core/querying/related-data#related-data-and-serialization

public void ConfigureServices(IServiceCollection services)
{
...

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

...
}
 1
Author: Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-09 15:31:46

La gente ya ha hablado acerca de [JsonIgnore] para ser añadido a la propiedad virtual en la clase, por ejemplo:

[JsonIgnore]
public virtual Project Project { get; set; }

También compartiré otra opción, [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] que omite la propiedad de serialización solo si es null.

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public virtual Project Project { get; set; }
 1
Author: Ali Raza,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-12 19:55:55

Simplemente coloque Configuration.ProxyCreationEnabled = false; dentro del archivo de contexto; esto resolverá el problema.

public demEntities()
    : base("name=demEntities")
{
    Configuration.ProxyCreationEnabled = false;
}
 0
Author: Fravius Kalisa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-05 15:30:09

Para no loopear esto funcionó para mí-
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,

Lo he resuelto todo aquí-Serialización de Entity Framework children con. Net Core 2 WebAPI https://gist.github.com/Kaidanov/f9ad0d79238494432f32b8407942c606

Apreciará cualquier comentario. tal vez alguien pueda usarlo alguna vez.

 -1
Author: Tzvi Gregory Kaidanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-18 10:32:30

Me gustó la solución que lo hace desde Application_Start() como en la respuesta aquí

Aparentemente no pude acceder a los objetos json en JavaScript usando la configuración dentro de mi función como en la respuesta de DalSoft, ya que el objeto devuelto tenía "\n \r" en todo el (key, val) del objeto.

De todos modos, lo que funciona es genial (porque los diferentes enfoques funcionan en diferentes escenarios basados en los comentarios y preguntas formuladas), aunque una forma estándar de hacerlo sería preferible con alguna buena documentación que respalde el enfoque.

 -2
Author: rey_coder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:24