i've got simple data model involving weeds , weed families.
weedfamily <-1---*-> weed
(weedfamily , weed have one-to-many relationship)
i'm attempting complete first apicontroller can retrieve data json angularjs application. when access /weedapi/
url in application, following error. i'm pretty sure problem have circular references between weed
, weedfamily
.
how should change data model json serialization work while maintaining bi-directional quality of weed
-weedfamily
relationship?
(ie. want still able build expressions following:
weeddata.getfamilies()["mustard"].weeds.count
and
weeddata.getweeds()[3].family.weeds
)
the error:
<error> <message>an error has occurred.</message> <exceptionmessage> 'objectcontent`1' type failed serialize response body content type 'application/xml; charset=utf-8'. </exceptionmessage> <exceptiontype>system.invalidoperationexception</exceptiontype> <stacktrace/> <innerexception> <message>an error has occurred.</message> <exceptionmessage> object graph type 'weedcards.models.weedfamily' contains cycles , cannot serialized if reference tracking disabled. </exceptionmessage> <exceptiontype> system.runtime.serialization.serializationexception </exceptiontype> <stacktrace> @ system.runtime.serialization.xmlobjectserializerwritecontext.onhandlereference(xmlwriterdelegator xmlwriter, object obj, boolean cancontaincyclicreference) @ writeweedtoxml(xmlwriterdelegator , object , xmlobjectserializerwritecontext , classdatacontract ) @ system.runtime.serialization.classdatacontract.writexmlvalue(xmlwriterdelegator xmlwriter, object obj, xmlobjectserializerwritecontext context) @ system.runtime.serialization.xmlobjectserializerwritecontext.writedatacontractvalue(datacontract datacontract, xmlwriterdelegator xmlwriter, object obj, runtimetypehandle declaredtypehandle) @ system.runtime.serialization.xmlobjectserializerwritecontext.serializewithoutxsitype(datacontract datacontract, xmlwriterdelegator xmlwriter, object obj, runtimetypehandle declaredtypehandle) @ system.runtime.serialization.xmlobjectserializerwritecontext.internalserialize(xmlwriterdelegator xmlwriter, object obj, boolean isdecl...etc </stacktrace> </innerexception> </error>
my data:
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"]) }; } }
my model classes:
[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 + ")"; } }
and
[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>(); } }
finally, apicontroller:
public class weedapicontroller : apicontroller { // // get: /weedapi/ public ienumerable<weed> getallweeds() { return weeddata.getweeds(); } }
add [datacontract(isreference = true)]
objects have circular references.
[serializable] [datacontract(isreference = true)] public class weedfamily [serializable] [datacontract(isreference = true)] public class weed
see http://msdn.microsoft.com/en-us/library/vstudio/hh241056(v=vs.100).aspx