Using a .NET client app, I am trying to post an object A that includes a collection of objects B via asp .net web api JSON, have that create a LocalDB database, and store the data. Then fetch object A again.
The app includes 3 projects. A asp .net mvc 4 web api project, a .Net console app and a .Net class library. Both the asp .net app and console app reference the class library, which includes the class definitions for objects A and B.
Class library:
public class Actor
{
public Actor()
{
this.Movies = new HashSet<Movie>();
}
public int ActorID { get; set; }
public string Name { get; set; }
public virtual ICollection<Movie> Movies { get; set; }
}
public class Movie
{
public Movie()
{
this.Actors = new HashSet<Actor>();
}
public int MovieID { get; set; }
public string Name { get; set; }
public virtual ICollection<Actor> Actors { get; set; }
}
Console App:
Movie movie = new Movie()
{
Name = "Dr. No"
};
Actor actor = new Actor()
{
Name = "Sean Connery"
};
movie.Actors.Add(actor);
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:3654");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = client.PostAsJsonAsync<Movie>("api/movies", movie).Result;
response.EnsureSuccessStatusCode();
response = client.GetAsync("api/movies/1").Result;
response.EnsureSuccessStatusCode();
Movie newMovie = response.Content.ReadAsAsync<Movie>().Result;
}
asp .net mvc DbContext:
public class MediaContext : DbContext
{
public MediaContext()
{
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<Movie> Movies { get; set; }
public DbSet<Actor> Actors { get; set; }
}
Problem #1: It seems JSON doesn't like the circular reference, however if I don't add the collection to both objects, EF5 does not create a MoviesActors table to hold the reference.
Problem #2: Even if I add the reference in the controller, when I return that object, it doesn't return it with the Actors. E.g. I expected something like
Movie
{
MovieID = "1",
Name = "???",
Actors[] = { 1 }
}
But instead, Actors is just null.
Update: Here is the self-referencing exception:
ExceptionMessage=Self referencing loop detected with type 'System.Data.Entity.DynamicProxies.Movie_157D88BDC89E46A7CE4875C2970C7BBFB893972095EFA0745C2261AACC007969'. Path '[0].Actors[0].Movies'.
I managed to work around this exception using the method at How did I solve the Json serializing circular reference error? and just disabling the proxy. That solves problem #1. However when I get the Movies, they still come back with no Actors, even using Include("Actors"). I can see the reference has been created correctly in the intermediate table in the LocalDb.
Update 2
FINALLY figured this out, answer below.
Thanks so much!