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.