Entity framework self referencing loop detected

106

I have a strange error. I'm experimenting with a .NET 4.5 Web API, Entity Framework and MS SQL Server. I've already created the database and set up the correct primary and foreign keys and relationships.

I've created a .edmx model and imported two tables: Employee and Department. A department can have many employees and this relationship exists. I created a new controller called EmployeeController using the scaffolding options to create an API controller with read/write actions using Entity Framework. In the wizard, selected Employee as the model and the correct entity for the data context.

The method that is created looks like this:

public IEnumerable<Employee> GetEmployees()
{
    var employees = db.Employees.Include(e => e.Department);
    return employees.AsEnumerable();
}

When I call my API via /api/Employee, I get this error:

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; ...System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.Employee_5D80AD978BC68A1D8BD675852F94E8B550F4CB150ADB8649E8998B7F95422552'. Path '[0].Department.Employees'.","ExceptionType":"Newtonsoft.Json.JsonSerializationException","StackTrace":" ...

Why is it self referencing [0].Department.Employees? That doesn't make a whole lot of sense. I would expect this to happen if I had circular referencing in my database but this is a very simple example. What could be going wrong?

This question is tagged with c# serialization entity-framework-4 asp.net-web-api

~ Asked on 2013-10-19 15:26:19

The Best Answer is


175

Well the correct answer for the default Json formater based on Json.net is to set ReferenceLoopHandling to Ignore.

Just add this to the Application_Start in Global.asax:

HttpConfiguration config = GlobalConfiguration.Configuration;

config.Formatters.JsonFormatter
            .SerializerSettings
            .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;

This is the correct way. It will ignore the reference pointing back to the object.

Other responses focused in changing the list being returned by excluding data or by making a facade object and sometimes that is not an option.

Using the JsonIgnore attribute to restrict the references can be time consuming and if you want to serialize the tree starting from another point that will be a problem.

~ Answered on 2015-05-13 00:06:36


55

This happens because you're trying to serialize the EF object collection directly. Since department has an association to employee and employee to department, the JSON serializer will loop infinetly reading d.Employee.Departments.Employee.Departments etc...

To fix this right before the serialization create an anonymous type with the props you want

example (psuedo)code:

departments.select(dep => new { 
    dep.Id, 
    Employee = new { 
        dep.Employee.Id, dep.Employee.Name 
    }
});

~ Answered on 2013-10-19 15:29:54


Most Viewed Questions: