How did I resolve the circular reference problem in Json serialization?

entity-framework json serialization

Question

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.

1
12
5/23/2017 10:27:11 AM

Accepted Answer

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.

9
10/17/2012 3:08:39 AM

Popular Answer

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 ;-)



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow