I'm creating an ASP.NET Web API with Entity Framework following the Code First Approach. I have a very simple model, which consists of a one-to-many relationship between a House and a Room:
House.cs
public class House
{
public int ID { get; set; }
public string Address { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
public House()
{
Rooms = new List<Room>();
}
}
Room.cs
public class Room
{
public int ID { get; set; }
public string Name { get; set; }
public int HouseID { get; set; }
public virtual House House { get; set; }
}
I have purposely added the virtual keyword to the Rooms attribute in the House class and to the House attribute in the Room class because I want to be able to see all the Rooms that a House has when I consult a House, and I want to see the House of a Room when I consult said Room (Lazy Loading).
However, when I make a GET request to my controller, the serialization of the entities fails, and it returns a XML (or JSON) full of errors:
api/houses (with Lazy Loading)
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'.
</ExceptionMessage>
<ExceptionType>System.InvalidOperationException</ExceptionType>
<StackTrace/>
<InnerException>
<Message>An error has occurred.</Message>
<ExceptionMessage>
Type 'System.Data.Entity.DynamicProxies.House_49DC0BEAA9C67FACDA33CEE81852FA2D80C04F62C6838F92ACD2A490CECF86B5' with data contract name 'House_49DC0BEAA9C67FACDA33CEE81852FA2D80C04F62C6838F92ACD2A490CECF86B5:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver if you are using DataContractSerializer or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to the serializer.
</ExceptionMessage>
...
</Error>
If I "disable" Lazy Loading by removing the virtual keyword from the attributes, the entities are serialized correctly, but I no longer have access to the associated entities. If I make a GET request to fetch all the houses, I no longer have access to the House's Rooms:
api/houses (without Lazy Loading)
<ArrayOfHouse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/REM.Models">
<House>
<Address>Boaty McBoatface Street 123</Address>
<ID>1</ID>
<Rooms/>
</House>
</ArrayOfHouse>
I tried using Eager Loading to solve my problem by removing the virtual keywords and explicitly loading the Rooms in the GET method of the Houses controller like this:
HousesController.cs
public IQueryable<House> GetHouses()
{
return db.Houses.Include(r => r.Rooms);
}
but it still failed to serialize the XML/JSON, showing me the exact same error message as when I tried to make a GET request with Lazy Loading.
I understand that all these problems may have something to do with circular dependency that is probably occurring between my two entities, but I have no idea how to solve it. So, to summarize all of this in one question:
Is there a way to make a request that will return all Houses with their respective Rooms, (without using auxiliary POCO (DTO))?