I love the Entity Framework CodeFirst stuff, combined with scaffolding, it makes development go so fast. Fast that is until you drop an API into the mix and want that to serve Json.
Here’s my EF Model. Lots of lovely navigation properties allowing me to get from any entity to any other one. Handy-dandy in .NET land…

But no-bueno when serializing using the out of the box Json serializer…
[HttpGet] public JsonResult Get(int id) { return Json(itemcategoryRepository.Find(id), JsonRequestBehavior.AllowGet); }
Now, this sucks because how awesomely elegant is that code? What you get is an error like this:
A circular reference was detected while serializing an object of type ‘System.Data.Entity.DynamicProxies.ItemCategory_A79…’.
Json Serialization Options
There are a few ways to go here – you could use ViewModels everywhere and sloppy-copy properties across as needed. Even with Automapper to take the drugery out of this, it rubs me the wrong way – what’s the point of using EF if I still have to have a separate set of Poco ViewModels?
Another option is to add a .ToJson method to the EF classes, and emit strings. Lots of control, but… meh.
Using Json.net comes up a lot, but it’s also labor intensive.
What I ended up doing is using Linq to project the EF object graph into an anonymous object graph. Here’s an example that serializes two levels of objects (a list of ItemCategories, each of which can contain a list of Items – see the object model above)
[HttpGet] public JsonResult List() { var data = itemcategoryRepository .AllIncluding(itemcategory => itemcategory.Items); //Project into anonymous objects because Serializers //can't handle circular refs in the EF magic var collection = data.Select(x => new { id = x.Id, name = x.Name, items = x.Items.Select(item => new { id=item.Id, name = item.Name }) }); return Json(collection, JsonRequestBehavior.AllowGet); }
I like this solution because I have control of the Json in the controller, rather than forcing an object to always serialize the same way in all cases (sometimes I want the Item to serialize it’s Entries, but only when I’m getting a single Item).
Funny again Mr. Bouman…I literally did the EXACT same thing yesterday, for the exact same reasons. My only fear is the cost (in memory) of creating so many anonymous types within each request. I’m now thinking dynamic types are maybe a little more efficient….em?
Interesting solution, in this scenario I use view models and AutoMapper. However, you end up doing a lot of maintenance on mapping logic. I tend to like to move the logic away from the controller. Another option is to push this aggregation to the db and use a view.
you probably won’t like this idea either since you don’t want poco view models, but automapper makes it stupid easy to do.
and you’re basically just making anonymous poco view models the way you’re doing it. But the dynamic ness of how you’re doing it is attractive.
Right – it’s the same thing, but with a little more freedom. Not sure how this would scale up to “Twitter” but that’s a whole other bag of cats