Traté de serializar la clase POCO que se generó automáticamente a partir de Entity Data Model .edmx y cuando usé
JsonConvert.SerializeObject
Tuve el siguiente error:
Error Se produce un bucle de auto referencia para el tipo System.data.entity.
¿Cómo resuelvo este problema?
json
serialization
json.net
NevenHuynh
fuente
fuente
async
llamada al método (aTask
) y olvidé prefijar laawait
declaración.Respuestas:
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 serializador json.net tiene una opción para ignorar las referencias circulares. Ponga el siguiente código en el
WebApiConfig.cs
archivo:La solución simple hará que el serializador ignore la referencia, lo que causará un bucle. Sin embargo, tiene limitaciones:
Si desea utilizar esta solución en un proyecto ASP.NET que no sea api, puede agregar la línea anterior
Global.asax.cs
, pero primero agregue:Si desea usar esto en el proyecto .Net Core , puede cambiarlo
Startup.cs
como:Solución 2: preservar la referencia circular a nivel mundial
Esta segunda solución es similar a la primera. Simplemente cambie el código a:
La forma de los datos cambiará después de aplicar esta configuración.
$ 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.
Solución 3: ignorar y preservar los atributos de referencia
Esta solución es decorar atributos en la clase de modelo para controlar el comportamiento de serialización a nivel de modelo o propiedad. Para ignorar la propiedad:
JsonIgnore es para JSON.NET e IgnoreDataMember es para XmlDCSerializer. Para preservar la referencia:
JsonObject(IsReference = true)]
es para JSON.NET y[DataContract(IsReference = true)]
es para XmlDCSerializer. Tenga en cuenta que: después de aplicarDataContract
en la clase, debe agregarDataMember
a las propiedades que desea serializar.Los atributos se pueden aplicar en el serializador json y xml y ofrece más controles en la clase de modelo.
fuente
[JsonIgnore]
el atributo anterior funcionó para mí.Utilice JsonSerializerSettings
ReferenceLoopHandling.Error
(predeterminado) producirá 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 hijo de sí mismo.Ejemplo:
Si tiene que serializar un objeto anidado indefinidamente, puede usar PreserveObjectReferences para evitar una excepción StackOverflowException.
Ejemplo:
Elija lo que tenga sentido para el objeto que está serializando.
Referencia http://james.newtonking.com/json/help/
fuente
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
funcionarReferenceLoopHandling.Serialize
provocará que el serializador entre en un bucle recursivo infinito y desborde la pila.La solución es ignorar las referencias de bucle y no serializarlas. Este comportamiento se especifica en
JsonSerializerSettings
.Individual
JsonConvert
con sobrecarga:Configuración global con código
Application_Start()
en Global.asax.cs:Referencia: https://github.com/JamesNK/Newtonsoft.Json/issues/78
fuente
La forma más sencilla de hacer esto es instalar Json.NET desde nuget y agregar el
[JsonIgnore]
atributo a la propiedad virtual en la clase, por ejemplo:Aunque en estos días, creo un modelo con solo las propiedades que quiero que pasen para que sea más ligero, no incluya colecciones no deseadas y no pierdo mis cambios cuando reconstruyo los archivos generados ...
fuente
En .NET Core 1.0, puede establecer esto como una configuración global en su archivo Startup.cs:
fuente
Si está utilizando .NET Core 2.x, actualice su sección ConfigureServices en Startup.cs
https://docs.microsoft.com/en-us/ef/core/querying/related-data#related-data-and-serialization
Si está utilizando .NET Core 3.x sin MVC, sería:
Este manejo del bucle de referencia es casi obligatorio si está utilizando Entity Framework y el patrón de diseño de base de datos primero.
fuente
services.AddMvc()
?Para serializar usin NEWTONSOFTJSON cuando tiene un problema de bucle, en mi caso no necesité modificar global.asax o apiconfig. Solo uso JsonSerializesSettings ignorando el manejo de Looping.
fuente
Newtonsoft.Json.JsonConvert.SerializeObject(objToSerialize, new Newtonsoft.Json.JsonSerializerSettings() {ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore});
Podemos agregar estas dos líneas al constructor de la clase DbContext para deshabilitar el bucle de referencia automática, como
fuente
También puede aplicar un atributo a la propiedad. El
[JsonProperty( ReferenceLoopHandling = ... )]
atributo se adapta bien a esto.Por ejemplo:
Espero que ayude, Jaans
fuente
Para ignorar las referencias de bucle y no serializarlas globalmente en MVC 6, use lo siguiente en startup.cs:
fuente
Use esto en
WebApiConfig.cs
clase:fuente
Para mí tuve que tomar una ruta diferente. En lugar de tratar de arreglar el serializador JSON.Net tuve que ir después de Lazy Loading en mi contexto de datos.
Acabo de agregar esto a mi repositorio base:
El objeto "contexto" es un parámetro constructor que uso en mi repositorio base porque uso la inyección de dependencia. En su lugar, puede cambiar la propiedad ProxyCreationEnabled en cualquier lugar donde cree una instancia de su contexto de datos.
http://techie-tid-bits.blogspot.com/2015/09/jsonnet-serializer-and-error-self.html
fuente
Tuve esta excepción y mi solución de trabajo es fácil y simple,
Ignore la propiedad referenciada agregando el atributo JsonIgnore:
Restablezca la propiedad cuando la deserialice:
usando Newtonsoft.Json;
fuente
[JsonIgnore]
Equipo:
Esto funciona con ASP.NET Core; El desafío a lo anterior es cómo 'configura la configuración para ignorar'. Dependiendo de cómo configure su aplicación, puede ser bastante difícil. Esto es lo que funcionó para mí.
Esto se puede colocar en su sección de vacío público ConfigureServices (servicios IServiceCollection).
fuente
La gente ya ha hablado de que se agregó [JsonIgnore] a la propiedad virtual en la clase, por ejemplo:
También compartiré otra opción, [JsonProperty (NullValueHandling = NullValueHandling.Ignore)] que omite la propiedad de la serialización solo si es nula:
fuente
Para .NET Core 3.0, actualice la clase Startup.cs como se muestra a continuación.
Ver: https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-core-3-0-preview-5/
fuente
Simplemente colóquelo
Configuration.ProxyCreationEnabled = false;
dentro del archivo de contexto; Esto solucionará el problema.fuente
Mi problema resuelto con la configuración personalizada JsonSerializerSettings:
fuente
Asegúrese también de usar wait y async en su método. Puede obtener este error si su objeto no está serializado correctamente.
fuente
Estaba enfrentando el mismo problema e intenté usar JsonSetting para ignorar el error de autorreferencia que funciona un poco hasta que obtuve una clase que hace una autorreferencia muy profunda y mi proceso dot-net se cuelga del valor de escritura de Json.
Mi problema
Puede ver el problema en la clase de usuario que hace referencia a la clase CompanyUser , que es una referencia automática.
Ahora, estoy llamando al Método GetAll que incluye todas las propiedades relacionales.
En esta etapa, mi proceso DotNetCore se cuelga en Ejecutar JsonResult, escribiendo valor ... y nunca llega. En mi Startup.cs, ya configuré JsonOption. Por alguna razón, EFCore incluye propiedades anidadas que no le estoy pidiendo a Ef.
el comportamiento esperado debería ser este
entonces
en esta etapa solo debería obtener este "Company.CompanyUsers.First (). User.DisplayName" y no debería darme Company.CompanyUsers.First (). User.CompanyUsers que causa el problema de autorreferencia; Técnicamente no debería darme User.CompanyUsers como CompanyUsers es una propiedad de navegación. Pero, EfCore se emociona mucho y me da User.CompanyUsers .
Entonces, decidí escribir un método de extensión para que la propiedad se excluya del objeto (en realidad no es excluyente, solo establece la propiedad en nulo). No solo eso también funcionará en las propiedades de la matriz. a continuación se muestra el código que también voy a exportar el paquete nuget para otros usuarios (no estoy seguro si esto incluso ayuda a alguien). La razón es simple porque soy demasiado vago para escribir .Seleccione (n => new {n.p1, n.p2}); ¡No quiero escribir una declaración select para excluir solo 1 propiedad!
Este no es el mejor código (lo actualizaré en algún momento) como lo he escrito rápidamente y aunque esto podría ayudar a alguien que quiera excluir (establecer nulo) en el objeto con matrices también.
la clase de extensión anterior le dará la capacidad de establecer la propiedad en nulo para evitar el bucle de autorreferencia incluso en matrices.
Generador de expresiones
Usos:
Clases de modelo
Datos ficticios
Casos:
Caso 1: excluir solo propiedades sin ninguna matriz
Caso 2: excluir propiedad con 1 matriz
Caso 3: excluir propiedad con 2 matrices anidadas
Caso 4: EF GetAll Query con incluye
Ha notado que el método Explode () también es un método de extensión solo para que nuestro generador de expresiones obtenga la propiedad de la propiedad de matriz. Siempre que haya una propiedad de matriz, use .Explode (). YourPropertyToExclude o .Explode (). Property1.MyArrayProperty.Explode (). MyStupidProperty . El código anterior me ayuda a evitar la autorreferencia tan profunda como quiero. ¡Ahora puedo usar GetAll y excluir la propiedad que no deseo!
¡Gracias por leer esta gran publicación!
fuente
Por no repetir esto funcionó para mí
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
Lo he resuelto todo aquí: serialización de niños de Entity Framework con .Net Core 2 WebAPI https://gist.github.com/Kaidanov/f9ad0d79238494432f32b8407942c606
Agradeceré cualquier comentario. Tal vez alguien pueda usarlo alguna vez.
fuente
Código C #:
fuente
Me gustó la solución que lo hace
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 toda la (clave, val) del objeto.
De todos modos, lo que sea que funcione es genial (porque los diferentes enfoques funcionan en diferentes escenarios basados en los comentarios y las preguntas formuladas), aunque sería preferible una forma estándar de hacerlo con una buena documentación que respalde el enfoque.
fuente