He estado experimentando con la creación de un sitio web que aprovecha MVC con JSON para mi capa de presentación y el marco de Entidad para el modelo de datos / base de datos. My Issue entra en juego con la serialización de mis objetos Model en JSON.
Estoy usando el primer método de código para crear mi base de datos. Al hacer el primer método de código, una relación uno a muchos (padre / hijo) requiere que el hijo tenga una referencia de regreso al padre. (Código de ejemplo puede ser un error tipográfico pero obtienes la imagen)
class parent
{
public List<child> Children{get;set;}
public int Id{get;set;}
}
class child
{
public int ParentId{get;set;}
[ForeignKey("ParentId")]
public parent MyParent{get;set;}
public string name{get;set;}
}
Cuando se devuelve un objeto "primario" a través de un JsonResult, se genera un error de referencia circular porque "secundario" tiene una propiedad de la clase principal.
He probado el atributo ScriptIgnore pero pierdo la capacidad de mirar los objetos secundarios. Tendré que mostrar información en una vista padre-hijo en algún momento.
He tratado de hacer clases base para padres e hijos que no tienen una referencia circular. Lamentablemente, cuando intento enviar el baseParent y el baseChild, JSON Parser los lee como sus clases derivadas (estoy bastante seguro de que este concepto se me escapa).
Base.baseParent basep = (Base.baseParent)parent;
return Json(basep, JsonRequestBehavior.AllowGet);
La única solución que se me ocurrió es crear modelos "Ver". Creo versiones simples de los modelos de bases de datos que no incluyen la referencia a la clase principal. Cada uno de estos modelos de vista tiene un método para devolver la Versión de la base de datos y un constructor que toma el modelo de la base de datos como parámetro (viewmodel.name = databasemodel.name). Este método parece forzado aunque funciona.
NOTA: Estoy publicando aquí porque creo que esto es más digno de discusión. Podría aprovechar un patrón de diseño diferente para superar este problema o podría ser tan simple como usar un atributo diferente en mi modelo. En mi búsqueda no he visto un buen método para superar este problema.
Mi objetivo final sería tener una buena aplicación MVC que aproveche en gran medida JSON para comunicarse con el servidor y mostrar datos. Mientras mantengo un modelo consistente en todas las capas (o lo mejor que se me ocurre).
fuente
Una alternativa más simple a intentar serializar los objetos sería deshabilitar la serialización de los objetos primarios / secundarios. En su lugar, puede realizar una llamada por separado para recuperar los objetos principales / secundarios asociados cuando los necesite. Esto puede no ser ideal para su aplicación, pero es una opción.
Para hacer esto, puede configurar un DataContractSerializer y establecer la propiedad DataContractSerializer.PreserveObjectReferences en 'falso' en el constructor de su clase de modelo de datos. Esto especifica que las referencias a objetos no deben conservarse al serializar las respuestas HTTP.
Ejemplos:
Formato Json:
Formato XML:
Esto significa que si busca un elemento que tiene objetos secundarios referenciados, los objetos secundarios no se serializarán.
Vea también la clase DataContractsSerializer .
fuente
Serializador JSON que se ocupa de referencias circulares
Aquí hay un ejemplo de Jackson personalizado
JSONSerializer
que trata con referencias circulares serializando la primera aparición y almacenando un *reference
a la primera aparición en todas las ocurrencias posteriores.Manejo de referencias circulares al serializar objetos con Jackson
Fragmento parcial relevante del artículo anterior:
fuente
Enviar la mínima cantidad de datos es la única respuesta correcta. Cuando envía datos desde la base de datos, generalmente no tiene sentido enviar cada columna con todas las asociaciones. Los consumidores no deberían tener que lidiar con estructuras y asociaciones de bases de datos, es decir, con bases de datos. Esto no solo ahorrará ancho de banda, sino que también es mucho más fácil de mantener, leer y consumir. Consulte los datos y luego ejecútelos para lo que realmente necesita para enviar eq. El mínimo indispensable.
fuente
.Include(x => x.TableName )
no devolver relaciones (de la tabla principal a la tabla dependiente), o solo devolver una fila de datos, ARREGLAR AQUÍ:/programming/43127957/include-not-working-in-net-core-returns-one-parent
Además, en Startup.cs asegúrese de tener esto en la parte superior:
fuente