Q:

ASP.NET MVC4 Web API Controller serialization

I am trying to create a RESTful web service that returns a list of products using ASP.NET MVC4 Web API. Here is my controller class
public class ProductController : ApiController
{
    public IEnumerable<Product> GetProducts()
    {
        WebCatalogContext dbcontext = DatabaseConfig.Instance.Context;
        List<Product> plist = dbcontext.Products.ToList();
        return plist;
    }
}

When I run my service and call the following URL from my browser :/api/Product, I get System.Runtime.Serialization.SerializationException. I looked into my plist object and there is no problem with it.
Here is my data model:
[DataContract(Name = "p")]
[Serializable]    
public class Product
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [DataMember(Name = "id")]
    public int Id { get; set; } 

    [Required, MaxLength(50)]
    [DataMember(Name = "ti")]
    public string Title { get; set; }

    [Required]
    [DataMember(Name = "de")]
    public string Description { get; set; }

    [Required]
    [DataMember(Name = "ph")]
    public string PhotoURL { get; set; }

    [DataMember(Name = "ca")]        
    public virtual ProductCategory Category { get; set; }
}

[DataContract(Name="pc")]
[Serializable]
public class ProductCategory
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [DataMember(Name="id")]
    public int Id { get; set; }

    [DataMember(Name="nm")]
    public string Name { get; set; }
}

When I remove the reference to ProductCategory from my Product class, all things work just fine. But, when I include it I get the following exception. 
Type 'System.Data.Entity.DynamicProxies.Product_664E9A0AA1F165A26C342B508BFFF1279FD3FE059285225BDA19F407A29A9CAD' with data contract name 'Product_664E9A0AA1F165A26C342B508BFFF1279FD3FE059285225BDA19F407A29A9CAD:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver 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 DataContractSerializer.
Any idea about what I am missing?
Regards

A:

Entity Framework has wrapped your POCO with an EF Proxy POCO so it can perform lazy loading - this uses the Virtual attribute to create a 'lazy-loadable' navigation property. I expect that is where the serialization error comes from.
You could make a new class and map the POCO to that - then pass the DTO style class from the controller. I've never returned an EF object directly from the API (I always map to some something else) so I don't know another option.
EF POCO to DTO (data transfer object) is relatively painless if you use a tool like http://valueinjecter.codeplex.com/ or http://automapper.org/

