una true serializar referencias referencia qué para objeto mecanismos manejar las isreference formato existen detectó dentro circulares c# oop asp.net-apicontroller

c# - true - dentro de una api qué mecanismos existen para manejar las referencias circulares en formato json



Referencias circulares que impiden la serialización del objeto gráfico. (1)

Tengo un modelo de datos simple que involucra a Weeds y Weed Families

WeedFamily <-1---*-> Weed (WeedFamily y Weed tienen una relación de uno a muchos)

Estoy intentando completar mi primer ApiController para poder recuperar fácilmente mis datos como JSON para una aplicación AngularJS. Cuando /WeedAPI/ URL en mi aplicación, obtengo el siguiente error. Estoy bastante seguro de que el problema es que tengo referencias circulares entre Weed y WeedFamily .

¿Cómo debo cambiar mi modelo de datos para que la serialización JSON funcione mientras se mantiene la calidad bidireccional de la relación Weed - WeedFamily ?

(es decir, quiero poder construir expresiones como las siguientes:

WeedData.GetFamilies()["mustard"].Weeds.Count

y

WeedData.GetWeeds()[3].Family.Weeds

)

El error:

<Error> <Message>An error has occurred.</Message> <ExceptionMessage> The ''ObjectContent`1'' type failed to serialize the response body for content type ''application/xml; charset=utf-8''. </ExceptionMessage> <ExceptionType>System.InvalidOperationException</ExceptionType> <StackTrace/> <InnerException> <Message>An error has occurred.</Message> <ExceptionMessage> Object graph for type ''WeedCards.Models.WeedFamily'' contains cycles and cannot be serialized if reference tracking is disabled. </ExceptionMessage> <ExceptionType> System.Runtime.Serialization.SerializationException </ExceptionType> <StackTrace> at System.Runtime.Serialization.XmlObjectSerializerWriteContext.OnHandleReference(XmlWriterDelegator xmlWriter, Object obj, Boolean canContainCyclicReference) at WriteWeedToXml(XmlWriterDelegator , Object , XmlObjectSerializerWriteContext , ClassDataContract ) at System.Runtime.Serialization.ClassDataContract.WriteXmlValue(XmlWriterDelegator xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract dataContract, XmlWriterDelegator xmlWriter, Object obj, RuntimeTypeHandle declaredTypeHandle) at System.Runtime.Serialization.XmlObjectSerializerWriteContext.InternalSerialize(XmlWriterDelegator xmlWriter, Object obj, Boolean isDecl...etc </StackTrace> </InnerException> </Error>

Mis datos:

public class WeedData { public static Dictionary<string,WeedFamily> GetFamilies(){ return new Dictionary<string,WeedFamily> { {"mustard",new WeedFamily("Mustard","Brassicaceae")} ,{"pigweed",new WeedFamily("Pigweed","Amaranthus")} ,{"sunflower",new WeedFamily("Sunflower","Asteraceae")} }; } public static List<Weed> GetWeeds(){ var Families = GetFamilies(); return new List<Weed> { new Weed("Hairy Bittercress","Cardamine hirsuta",Families["mustard"]) ,new Weed("Little Bittercress","Cardamine oligosperma",Families["mustard"]) ,new Weed("Shepherd''s-Purse","Capsella bursa-pastoris",Families["mustard"]) ,new Weed("Wild Mustard","Sinapis arvensis / Brassica kaber",Families["mustard"]) ,new Weed("Wild Radish","Raphanus raphanistrum",Families["mustard"]) ,new Weed("Radish","Raphanus sativus",Families["mustard"]) ,new Weed("Redroot Pigweed","Amaranthus retroflexus",Families["pigweed"]) ,new Weed("Prickly Lettuce","Lactuca serriola",Families["sunflower"]) ,new Weed("Spiny Sowthistle","Sonchus asper",Families["sunflower"]) ,new Weed("Annual Sowthistle","Sonchus oleraceus",Families["sunflower"]) }; } }

Mis clases modelo:

[Serializable] public class Weed { public string CommonName; public string LatinName; public List<WeedPhoto> Photos; public WeedFamily Family; public Weed(string commonName, string latinName) { CommonName = commonName; LatinName = latinName; } public Weed(string commonName, string latinName, WeedFamily family) { CommonName = commonName; LatinName = latinName; Family = family; Family.Weeds.Add(this); } override public string ToString() { return CommonName + " (" + LatinName + ")"; } }

y

[Serializable] public class WeedFamily { public string CommonName; public string LatinName; public List<Weed> Weeds; public WeedFamily(string commonName, string latinName) { CommonName = commonName; LatinName = latinName; Weeds = new List<Weed>(); } }

Finalmente, el ApiController:

public class WeedAPIController : ApiController { // // GET: /WeedAPI/ public IEnumerable<Weed> GetAllWeeds() { return WeedData.GetWeeds(); } }