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?
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.
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
}
});
I had same problem and found that you can just apply the [JsonIgnore]
attribute to the navigation property you don't want to be serialised. It will still serialise both the parent and child entities but just avoids the self referencing loop.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With