I have the following model inside an entity framework:
public class Customer
{
[XmlIgnore]
public virtual ICollection<Customer> Children { get; set; }
public string Name { get; set; }
}
Now I try to serialize this using web api:
public class CustomerController:ApiController {
public HttpResponseMessage GetAll()
{
using (var tc = new DataContext())
{
List<Customer> allCustomers = tc.Customers.ToList();
return Request.CreateResponse(HttpStatusCode.OK, allCustomers);
}
}
}
When I do this and call the method using POST I receive the following error:
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8
InnerException: "Error getting value from 'Children' on 'System.Data.Entity.DynamicProxies.Customer"
InnerException(2): "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection."
customers.Children is currently an empty List.
My guess this problem occurs because Children is of the same type as Customer causing an "infinite serialization loop". (I got no better words to describe that)
I already tried XmlIgnore to prevent that property to be serialized but with no effect.
Don't declare that navigation property as
virtual
or disable Lazy Loading behavior. Lazy loading is enable by default and is achieved by creating instances of derived proxy types and then overridingvirtual
properties to add the loading hook. So, if you want to work with XML serializer I recommend you turn off lazy loading:In case you want to load the related entity (
Children
), you can use theInclude
extension method as part of a query. This behavior is called Eager Loading.These links can help you to understand better what I explain in my answer:
If you remove the
virtual
keyword from your navigation properties, the POCO entity not meet the requirements described in the second link, so, EF won't create a proxy class to lazy load your navigation properties. But if you disabled lazy loading, even when your navigation properties arevirtual
, they won't be loaded in any entity. It's good idea disable lazy loading when you are using a serializer. Most serializers work by accessing each property on an instance of a type.Just for the sake of knowledge: The following also works:
The magic is "JsonIgnore" there.
Nonetheless: @octavioccl 's answer is a much better solution which requires more work but creates better code.