I am using Entity Framework (code first) and I have mapped all my entities and disabled lazy loading. This works fine, but as soon as I try to do some Ajax work I start to get issues.
The first issue is with my User class. This looks like this:
public partial class User : IdentityUser
{
public string CompanyId { get; set; }
public string CreatedById { get; set; }
public string ModifiedById { get; set; }
public System.DateTime DateCreated { get; set; }
public Nullable<System.DateTime> DateModified { get; set; }
public System.DateTime LastLoginDate { get; set; }
public string Title { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
public string JobTitle { get; set; }
public string Telephone { get; set; }
public string Mobile { get; set; }
public string Photo { get; set; }
public string LinkedIn { get; set; }
public string Twitter { get; set; }
public string Facebook { get; set; }
public string Google { get; set; }
public string Bio { get; set; }
public string CompanyName { get; set; }
public string CredentialId { get; set; }
public bool IsLockedOut { get; set; }
public bool IsApproved { get; set; }
public bool CanEditOwn { get; set; }
public bool CanEdit { get; set; }
public bool CanDownload { get; set; }
public bool RequiresApproval { get; set; }
public bool CanApprove { get; set; }
public bool CanSync { get; set; }
public bool AgreedTerms { get; set; }
public bool Deleted { get; set; }
public Company Company { get; set; }
public User CreatedBy { get; set; }
public User ModifiedBy { get; set; }
public ICollection<Asset> Assets { get; set; }
public ICollection<Category> Categories { get; set; }
public ICollection<Collection> Collections { get; set; }
public ICollection<Comment> Comments { get; set; }
public ICollection<LocalIntegration> LocalIntegrations { get; set; }
public ICollection<Page> Pages { get; set; }
public ICollection<Rating> Ratings { get; set; }
public ICollection<Theme> Themes { get; set; }
public ICollection<Group> MemberOf { get; set; }
public ICollection<Category> ForbiddenCategories { get; set; }
public ICollection<Page> ForbiddenPages { get; set; }
}
Now, because Lazy loading is disabled, I use Eager loading instead and if I have a look at this when I called this method:
//
// AJAX: /Users/Get
public JsonResult Get()
{
try
{
using (var uow = new UnitOfWork<SkipstoneContext>())
{
var service = new UserService(uow, User.Identity.GetUserId(), this.CompanyId);
var u = service.GetAll("MemberOf");
return new JsonResult { Data = new { success = true, users = u } }; // Return our users
}
}
catch (Exception ex)
{
return new JsonResult { Data = new { success = false, error = ex.Message } };
}
}
I can clearly see that only the Members navigation property is populated. The rest are null as expected.
If I try to pass u to my JsonResult, this is where the problem arises. I get the error:
Self referencing loop detected for property 'CreatedBy' with type 'System.Data.Entity.DynamicProxies.User_E9B58CAAA82234358C2DE2AF8788D33803C4440F800EA8E015BE49C58B010EDF'. Path 'users[0]'.
In another post, I read that this happens because Json.Net tries to serialise and populate all navigation properties.
So, I created a new project and in that I created 2 models:
public class User
{
public User()
{
this.Id = Guid.NewGuid().ToString();
}
public string Id { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string CreatedById { get; set; }
public ICollection<Post> Posts { get; set; }
public User CreatedBy { get; set; }
}
public class Post
{
public string Id { get; set; }
public string Title { get; set; }
public string Message { get; set; }
public string CreatedById { get; set; }
public User CreatedBy { get; set; }
}
I would expect that running that, there would be a self referencing error because not only does User have many Post, it also has a User that created it.
So the method looks like this:
public JsonResult Get()
{
try
{
var user = new User()
{
UserName = "moo",
Email = "moo@moo.co.uk"
};
return new JsonResult { Data = new { sucess = true, user = user } };
}
catch (Exception ex)
{
return new JsonResult { Data = new { sucess = true, error = ex.Message } };
}
}
again, this is identical (to my eyes) to the first project. Anyway, when I run this, the project runs fine.
Can someone explain to me why this is happening and what I can do to solve it?