Sunday, 15 January 2012

c# - How Do You "Really" Serialize Circular Referencing Objects With Newtonsoft.Json? -



c# - How Do You "Really" Serialize Circular Referencing Objects With Newtonsoft.Json? -

i'm having problem getting info serialized correctly asp.net web api controller using newtonsoft.json.

here's think going on - please right me if i'm wrong. under circumstances (specifically when there aren't circular references in data) works you'd expect - list of populated objects gets serialized , returned. if introduce info causes circular reference in model (described below, , preservereferenceshandling.objects set) elements of list leading first object circular reference serialized in way client can "work with". "elements leading to" can of elements in info if it's ordered differently before sending things serializer, @ to the lowest degree 1 serialized in way client can "work with". empty objects end beingness serialized newtonsoft references ({$ref:x}).

for example, if have ef model finish navigation properties looks this:

in global.asax:

var json = globalconfiguration.configuration.formatters.jsonformatter; json.serializersettings.preservereferenceshandling = newtonsoft.json.preservereferenceshandling.objects;

here's fundamental query i'm doing using entity framework (lazy-loading off there aren't proxy classes here):

[httpget] [route("starting")] public ienumerable<balance> getstartingbalances() { using (mycontext db = new mycontext()) { var info = db.balances .include(x => x.source) .include(x => x.place) .tolist() homecoming data; } }

so far good, data populated.

if there no circular references, life grand. however, there 2 balance entities same source or place, serialization turns later balance objects of top-most list i'm returning newtonsoft references instead of full-fledged objects because serialized in balances property of source or place object(s):

[{"$id":"1","balanceid":4,"sourceid":2,"placeid":2 ...omitted clarity...},{"$ref":"4"}]

the problem client doesn't know {$ref:4} though humans understand what's going on. in case, means cannot utilize angularjs ng-repeat on entire list of balances json, because aren't true balance objects balance property bind. i'm sure there tons of other use-cases have same problem.

i can't turn off json.serializersettings.preservereferenceshandling = newtonsoft.json.preservereferenceshandling.objects because lots of other things break (which well-documented in 100 other questions here , elsewhere).

is there improve workaround apart going through entities in web api controller , doing

balance.source.balances = null;

to of navigation properties break circular references? because doesn't seem right either.

yes, using preservereferenceshandling.objects best way serialize object graph circular references, because produces compact json , preserves reference construction of object graph. is, when deserialize json objects (using library understands $id , $ref notation), each reference particular object point same instance of object, rather having multiple instances same data.

in case problem client side parser not understand $id , $ref notation produced json.net, references not beingness resolved. can fixed using javascript method reconstruct object references after deserializing json. see here , here examples.

another possibility might work, depending on situation, set referenceloophandling ignore when serializing instead of setting preservereferenceshandling objects. not perfect solution though. see this question detailed explanation of differences between using referenceloophandling.ignore , preservereferenceshandling.objects.

c# json entity-framework asp.net-web-api json.net

No comments:

Post a Comment