Going in circles with EF Code First and Web API
This was a new area of pain for me. While I’ve played around with EF Code First before, ASP.NET Web API is a new beast and mixing the two can be tricky. If you don’t know much about serialization and the issues with circular references, you’re about to learn. For the walkthrough below, I’m targeting MVC/Web API 4 RC bits.
The goal is to use EF Code First (CF) to generate our database, and then Web API to expose some REST’ful endpoints for querying the data. Simple stuff.
First, let’s define our data model. We’ll create a Person class and an Address class.
Now that we have a model, we can use the built-in controller scaffolding in Visual Studio (right-click on your Controllers folder) to quickly create a Web API controller with read/write actions based on the model class for Person.
This generates the following Web API controller code with a GET endpoint.
I intentionally added the “Include” so that we can pick up a person’s address as well when we query for them. Unfortunately, this will be the source of our troubles.
Okay, time to hit the endpoint. I’ll make a request via Fiddler.
Uh oh, an HTTP 500 isn’t good.
Looking at the JSON response that came back, we see this error message:
Self referencing loop detected for property ‘Person’ with type ‘System.Data.Entity.DynamicProxies.Person_<SNIP>’. Path ‘Address’.
Well that’s kind of self-explanatory. Our bi-directional navigation properties between our Person object and our Address object are creating a self referencing loop which is breaking Web API’s effort to serialize the objects as JSON. Note, this isn’t a bug with Web API IMO. It’s a basic serialization issue.
To work through this, we need to look under the hood of Web API’s JSON serialization process.
Internally, Web API uses Json.NET for serialization and by default the serializer is configured to throw an error when a reference loop is detected. Fortunately, this is something we can tweak via the “ReferenceLoopHandling” setting on the serializer. You can read more about this on the Json.NET serialization settings doc page.
We’ll set this to “ignore” loops in our “global.asax.cs” file.
Making the same request via Fiddler once more, we get the expected JSON.
Web API also supports XML serialization out of the box, and you’ll hit similar self referencing loop issues there as well, but I’ll leave that discussion to a future post.