1

I've built a small service using the ASP.NET Web Api. My domain classes looks like this:

 public class Drink : IEntity
{
    public Drink()
    {
        Ingridients = new List<Ingredient>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Ingredient> Ingridients { get; set; }
    public string Approach { get; set; }
}

public class Ingredient : IEntity
{
    public Ingredient()
    {
        Drinks = new List<Drink>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Drink> Drinks { get; set; }
}

My Repository Looks like this:

public IEnumerable<T> GetAll(){return _dbSet;}

And my controller looks like this:

    public IEnumerable<Drink> GetAllDrinks()
    {
        return _unitOfWork.Drinks.GetAll();
    }

When I make I request using fiddler the JSON result is the following:

{"Id":15,"Name":"Russian Energy","Ingridients":[],"Approach":"Mix Vodka with Redbull"}

As you can see the Ingridents array is empty. Why is that?

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
Ols1
  • 321
  • 3
  • 15
  • 1
    I added the json.net tag because this question is really, "why doesn't json.net serialize my EF graph correctly." Web-api is incidental to the problem. – Darrel Miller Jan 05 '13 at 16:41
  • Have a look at this question on SO .. http://stackoverflow.com/questions/5588143/ef-4-1-code-first-json-circular-reference-serialization-error – Rajesh Jan 14 '13 at 15:11
  • Also have a look at this blog that might be helpful: http://blog.davebouwman.com/2011/12/08/handling-circular-references-asp-net-mvc-json-serialization/ – Rajesh Jan 14 '13 at 15:19
  • Looks interesting, Rajesh. I'll have a cloer look at it ASAP – Ols1 Jan 17 '13 at 19:50

2 Answers2

2

You can try to use eager loading with Include:

Extend your GetAll method to allow eager loading:

//...
using System.Data.Entity;
//...

public IEnumerable<T> GetAll(params Expression<Func<T, object>>[] includes)
{
    IQueryable<T> query = _dbSet;
    if (includes != null)
    {
        foreach (var include in includes)
            query = query.Include(include);
    }
    return query;
}

Then use it in your controller like so:

public IEnumerable<Drink> GetAllDrinks()
{
    return _unitOfWork.Drinks.GetAll(d => d.Ingredients);
}
Slauma
  • 175,098
  • 59
  • 401
  • 420
  • Now I get a different error..like so An error has occurred. The 'ObjectContent`1' type failed to serialize the response body for content type 'application/xml; charset=utf-8'. System.InvalidOperationException An error has occurred. Object graph for type 'Gudo.Core.Model.Ingredient' contains cycles and cannot be serialized if reference tracking is disabled. – Ols1 Jan 05 '13 at 17:50
  • This error occurs after I applied the changes that Slauma suggested – Ols1 Jan 05 '13 at 17:51
  • @IAmSharp: Google for the error or ask a new question. There plenty of references about this problem over the Internet. For example: http://stackoverflow.com/a/658056/270591 or (for JSON.NET) http://johnnycode.com/2012/04/10/serializing-circular-references-with-json-net-and-entity-framework/ The error has nothing to do with your original problem that the ingredients are not loaded. – Slauma Jan 05 '13 at 18:19
  • Ok..I'll add a new question – Ols1 Jan 05 '13 at 19:37
0

Are you using Entity Framework Code First?

If so, you have to mark the navigation properties as virtual:

public class Drink : IEntity
{
    public Drink()
    {
        Ingridients = new List<Ingredient>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Ingredient> Ingridients { get; set; }
    public string Approach { get; set; }
}

public class Ingredient : IEntity
{
    public Ingredient()
    {
        Drinks = new List<Drink>();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Drink> Drinks { get; set; }
}
deerchao
  • 10,454
  • 9
  • 55
  • 60
  • Yes, I'm using CF. Marking the nav properties as virtual didn't help. I'm still getting the empty array. – Ols1 Jan 05 '13 at 15:17