I'have a application that has a relationship One to many with AspnetUser and when I do a GET request on Postman I don't receive all the user information, only a broken JSON with only the custom user data.
I've try to debug the code and I noticed before I send the information all data is inside the object that I send.
ControllerBase:
[HttpGet]
public async Task<IActionResult> GetClasses ()
{
var classes = await_repository.All.ToListAsync();
return Ok(classes);
}
Repository:
public IQueryable<TEntity> All => _context.Set<TEntity>().AsQueryable();
Classes Model
public partial class Classes
{
public Classes()
{
Users = new HashSet<UserApplication>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<UserApplication> Users { get; set; }
}
UserApplication
public class UserApplication : IdentityUser
{
public string Name { get; set; }
public int Age { get; set; }
public int ClassesId { get; set; }
public virtual Classes Classes { get; set; }
}
Entity Configuration
builder.HasOne(d => d.Classes)
.WithMany(p => p.Users)
.HasForeignKey(d => d.ClassesId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("Users_ClassesId_fkey");
So, when I debugged on Visual Studio the var classes has all attributes full, but when I use the Postman I got this result
Result of the GET on Postman
[{"id":1,"name":"Test","users":[{"name":"Teste123","age":18, "classesId":1
I read some articles saying that you have to make to table users to resolve this, but I felt like too "trick" to do this.
The problem of self-referencing loops during JSON serialization is connected to how EFCore loads related data (docs). When you load a collection, related entities may or may not be automatically populated depending on whether or not those object have been previously loaded. It's called automatic fix-up of navigation properties. Alternatively, they may be eagerly loaded via .Include()
.
Whenever you get a self-referencing graph of entities to be serialized, there are several options:
Newtonsoft.Json.ReferenceLoopHandling.Ignore
(officially recommended). It works but still can result in serializing excessive data if self-reference occurs deep in the hierarchy.
[JsonIgnore]
attribute on navigation properties. As you noted, attributes disappear when model classes are regenerated. Thus, their use can be inconvenient.
(Best choice) Pre-select a subset of properties:
var minimallyNecessarySet= _nwind.Products.Select(p => new {
p.ProductID,
p.ProductName,
p.UnitPrice,
p.CategoryID
});
return minimallyNecessarySet.ToList();
This approach has the advantage of serializing only required data. It's compatible with DevExtreme's DataSourceLoader
:
return DataSourceLoader.Load(minimallyNecessarySet, loadOptions);