In this article we see How to fix the WCF - Web API Error 'contains cycles and cannot be serialized if reference tracking is disabled'.
How to fix the WCF - Web API Error 'contains cycles and cannot be serialized if reference tracking is disabled'
This serialization error is originated when your Data Model contains an Entity with a property which references an object of the same type of the container class, or when you have many entities with relationships between them, and several of them are referenced by others in such a way that creates a circular self reference.
Let's say we have the following data Model , in which a "Blog" contains a reference to its "Blogger" , but this later owns many "Blogs":
That means, if you open some Blog , and open its Blogger property, you will then see the Blogs that the Blogger owns, and , between them , the original Blog that you opened earlier, and that is a circular reference.
This can happen for instance, when you have a WCF service or a Web API which use eager loading:
The MSDN web page for this "contains cycles and cannot be serialized if reference tracking is disabled" error addresses only the first study case, in which an object reference itself: for example, a "Person" class contains a property referencing some other "Person":
As it states, the solution is to add to the DataContract Attribute the "IsReference" boolean value set to "true". However , in most cases, you're prone to find the second XML-JSON serialization problem, in which several entities are related by ONE-TO-MANY relationships:
In this case, just make a list of the classes that appear REFERENCED by other classes, that means, the entities which are at the " 0 .. 1 " side of any one-to-many relationship. In our example, there are ONLY two classes like that: Blogger and Blog, because "Comment" is not referenced by any other.
Therefore, open the classes files and add to the DataContract attribute the "IsReference" set to true:
This way, the reference tracking will be enabled and the circular references will be fixed.
If you like, it's possible to define "Metadata classes" and set the Attributes there: continuing with our example, that will be like this:
After compilation-run, the WCF or WebAPI will render the data avoiding cycles, as follows:
Here you can see that a "Blog" contains a "Blogger" property, and when it tries to reference the containing object, it will be use the reference " z:Id=i1 " .
Same thing for the "Comments", while trying to reference the containing "Blog".
By Carmel Shvartzman
עריכה: כרמל שוורצמן