DCSIMG
Avoiding Circular Reference for Entity in JSON Serialization - Gil Fink's Blog

Gil Fink's Blog

Fink about IT

News

Microsoft MVP

My Facebook Profile My Twitter Profile My Linkedin Profile

Locations of visitors to this page

Creative Commons License

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.
© Copyright 2012 Gil Fink

Hebrew Articles

Index Pages

My OSS Projects

English Articles

Avoiding Circular Reference for Entity in JSON Serialization

Avoiding Circular Reference for Entity in JSON Serialization

One problem that I was facing yesterday while working on an ASP.NET MVC application was a JSON serialization issue. The problem was a circular reference caused by the DataContractJsonSerializer because of relations between the entity and other entities. In this post I’ll show you how you can use a simple workaround in order to avoid the problem.   

The JSON Serialization Error

Returning the output of the JSON method in an ASP.NET MVC controller with a JSON object graph based on an Entity Framework Code First object causes the following error – “A circular reference was detected while serializing an object of type ‘object name’”. Here is an example of a method that might cause the problem:

public ActionResult Details(int id)
    using (var context = new DbEntities())
    {             
        var entity = context.Entities.
          Include(e => e.OtherEntities).
          FirstOrDefault(e => e.EntityId == id);
        return Json(entity, JsonRequestBehavior.AllowGet);
    }
}

Pay attention that this is a fake method and isn’t a real method.

The error I was getting didn’t show up on the server side (nothing crashed). I found the error by inspecting Fiddler since the application kept on working but the client side callback wasn’t. Here is an example of the calling client side function which is using jQuery getJSON function:

function getDetails() {
    $.getJSON('/ApplicationName/Details/' + Id, {}, function (data) {
        fillDetails(data);
    });
}

The circular reference is a known problem that my colleague Ido wrote about in Microsoft Connect.
So how to avoid it?

The Workaround

Use a data projection to project only the relevant data that you need and send this data to the client side. This workaround will minimize the object that you are sending and also play a role as a ViewModel kind of object instead of an entity when it is available on the client side. Here is an example of using the workaround with the previous method:

public ActionResult Details(int id)
{
  using (var context = new DbEntities())
  {
    var entity = context.Entities.
      Include(g => g.OtherEntities).
      Select(e => new { 
        e.Id,
        e.Url,
        e.Name,
        e.OtherEntities
      }).
      FirstOrDefault(e => e.Id == id);
 
    return Json(entity, JsonRequestBehavior.AllowGet);
  }
}

Summary

The circular reference issue might happen also in WCF script services or in other places while serializing Entity Framework’s entities into JSON representation. The simple workaround is to create a projection of the data that you need and serialize it into JSON representation. One of the gains of this method is minimizing the response size from the server.

Comments

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# October 17, 2011 11:19 AM

Nuno Costa said:

I belive the same could be achived without projection, just disable LazyLoading an use the Include keyword for related entities

context.ContextOptions.LazyLoadingEnabled = false;

var query = from entity in context.Entities.Include("RelatedEntities")

           select entity;

# October 17, 2011 12:45 PM

Avoiding Circular Reference for Entity in JSON... | .NET, ADO.NET Entity Framework | Syngu said:

Pingback from  Avoiding Circular Reference for Entity in JSON... | .NET, ADO.NET Entity Framework | Syngu

# October 18, 2011 7:44 AM