JSON Serialization (ASP.Net Web API) fails because of self-referencing loop (it’s a common problem, Reason: an entity being requested lazy loads child entities and every child has a back reference to parent entity).
Work around I found, but doesn’t help me:
- Use [JsonIgnore] for navigation properties to be ignored: This solution works but doesn’t apply in my case. For Example: To get a Customer information along with his Orders, I would quickly add [JsonIgnore] to Customer property in Order class, but when I want to get an Order information along with the Customer details, since there’s [JsonIgnore] on Customer property, it won’t include Customer details.
- Change JSON.Net Serializer Settings to Preserve References: Can’t Preserve because I don’t need Circular referenced data.
- Disable Proxy Creation at the Data Context and use explicit loading(this should ideally solve the problem): Disabling proxy creation stops Lazy Loading and returns data without error, but when I explicitly Include child entities, I again the get the unexpected self-referencing loop error! The error is at the back-reference level to parent entity.
Any experiences along the same lines/suggestions?
This is what I ended up settling on, hopefully it helps someone else.
Say the EF classes are structured like this:
To keep serialization form happening in JSON.NET, you can extend the class and add a method with the name "ShouldSerialize" + property name like so:
If you wanted to get a little more fancy, you could add logic in the method so that it would serialize in certain cases. This allows you to keep serialization logic out of the EF Model First code creation as long as this code is in a different physical code file.
I tried all the suggested solutions but didn't work. Ended up with Overriding the JSON.Net Serializer’s DefaultContractResolver to this:
Then created a Static Class which returns a dictionary of Properties to be Ignored based on the Controller:
And inside every controller change the JSON Formatter something like:
Instead of letting the Entity Framework generate the model, use Code First with an existing database. Now you are more in control.
See this blog entry from Scott Guthrie