Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How did I solve the Json serializing circular reference error?

There is post here that asks how to solve the circular reference error when returning a serialized object via EF4 CTP5. I ran into this same problem with a WCF web forms project a while back.

I was able to "solve" this problem in my WCF/web forms project and in my MVC3 project. I don't think it matters what type of project as this appears to be a EF serialization "thing".

I solved the problem by disabling ProxyCreation in my ObjectContext constructor like this:

public class MyObjectContext : DbContext, IDbContext
{
     public MyObjectContext(string connectionStringName) : base(connectionStringName)
     {
        ((IObjectContextAdapter)this).ObjectContext.ContextOptions.ProxyCreationEnabled = false;
     }
     public DbSet<Product> Products {get;set;}
     //etc.
} 

My question is: Could someone explain why this would seemingly solve the problem?

I think the problem has to do with navigation properties in my POCO's but after that I am stumped. Thanks.

like image 241
trevorc Avatar asked Jan 21 '11 00:01

trevorc


2 Answers

If you turn off proxy creation you also turn off lazy loading. When serialization of entity occures it visits all navigation properties. If lazy loading is enabled it loads all related objects and tries to serialize them as well. Again it visits all their properties including navigation properties pointing back to parent object. At this point you have to say serialization that this property is circular reference or it will serialize the object again and continue in infinite loop.

The trick here could be to annotate your circular navigation property in child entity with the ScriptIgnore attribute.

like image 111
Ladislav Mrnka Avatar answered Oct 23 '22 10:10

Ladislav Mrnka


The circular reference happens because you use eager loading on the object.

You have a couple of methods:

  • Turn off eager loading when your loading your Query (linq or lambda) DbContext.Configuration.ProxyCreationEnabled = false;
  • Remove the virtual keyword from the Domainmodel
  • Include them while loading the objects
  • Detach the objects (= no eager loading functionality & no proxy)
    • Repository.Detach(entityObject)
    • DbContext.Entry(entityObject).EntityState = EntityState.Detached
  • Clone the properties
    • You could use something like AutoMapper to clone the object, don't use the ICloneable interface, because it also clones the ProxyProperties in the object, so that won't work.
  • In case you are building an API, try using a separte project with a different configuration (that doesn't return proxies)

PS. Proxies is the object that's created by EF when you load it from the Entity Framework. In short: It means that it holds the original values and updated values so they can be updated later. It handles other things to ;-)

like image 43
NicoJuicy Avatar answered Oct 23 '22 10:10

NicoJuicy