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.cs
pero 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