-1

I am using ASP CORE 2.1 and EF CORE to create Web API with 2 data table with 1 ForeignKey

Model:

 public partial class AuditInfo
{

    public int Id { get; set; }
    public string Level { get; set; }
    public string Period { get; set; }
    public string Auditor { get; set; }

    public virtual ICollection<Item> Items { get; set; }
}

  public partial class Item
{
    public int Id { get; set; }
    public string Ponumber { get; set; }
    public bool IsComplete { get; set; }

    public AuditInfo AuditInfo { get; set; }
}

public partial class VEDHOMEContext : DbContext
{
    public VEDHOMEContext()
    {

    }

    public VEDHOMEContext(DbContextOptions<VEDHOMEContext> options)
        : base(options)
    {

    }

    public virtual DbSet<AuditInfo> AuditInfo { get; set; }
    public virtual DbSet<Item> Item { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {




    }

     protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        modelBuilder
            .HasAnnotation("ProductVersion", "2.1.1-rtm-30846")
            .HasAnnotation("Relational:MaxIdentifierLength", 128)
            .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

        modelBuilder.Entity("auditAPI.Models.AuditInfo", b =>
        {
            b.Property<int>("Id")
                .ValueGeneratedOnAdd()
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

            b.Property<string>("Auditor");

            b.Property<string>("Level");

            b.Property<string>("Period");

            b.HasKey("Id");

            b.ToTable("AuditInfo");
        });

        modelBuilder.Entity("auditAPI.Models.Item", b =>
        {
            b.Property<int>("Id")
                .ValueGeneratedOnAdd()
                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

            b.Property<int?>("AuditInfoId");

            b.Property<bool>("IsComplete");

            b.Property<string>("Ponumber");

            b.HasKey("Id");

            b.HasIndex("AuditInfoId");

            b.ToTable("Item");
        });

        modelBuilder.Entity("auditAPI.Models.Item", b =>
        {
            b.HasOne("auditAPI.Models.AuditInfo", "AuditInfo")
                .WithMany("Items")
                .HasForeignKey("AuditInfoId");
        });


    }



}

Controller:

[Route("api/[controller]")]
[ApiController]
public class AuditInfoesController : ControllerBase
{
    private readonly VEDHOMEContext _context;

    public AuditInfoesController(VEDHOMEContext context)
    {
        _context = context;
    }

    // GET: api/AuditInfoes
    [HttpGet]
    public IEnumerable<AuditInfo> GetAuditInfo()
    {
        return _context.AuditInfo;
    }

    // GET: api/AuditInfoes/5
    [HttpGet("{id}")]
    public async Task<IActionResult> GetAuditInfo([FromRoute] int id)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var auditInfo = await _context.AuditInfo.FindAsync(id);

        if (auditInfo == null)
        {
            return NotFound();
        }

        return Ok(auditInfo);
    }

    // PUT: api/AuditInfoes/5
    [HttpPut("{id}")]
    public async Task<IActionResult> PutAuditInfo([FromRoute] int id, [FromBody] AuditInfo auditInfo)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != auditInfo.Id)
        {
            return BadRequest();
        }

        _context.Entry(auditInfo).State = EntityState.Modified;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!AuditInfoExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return NoContent();
    }

    // POST: api/AuditInfoes
    [HttpPost]
    public async Task<IActionResult> PostAuditInfo([FromBody] AuditInfo auditInfo)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _context.AuditInfo.Add(auditInfo);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetAuditInfo", new { id = auditInfo.Id }, auditInfo);
    }

    // DELETE: api/AuditInfoes/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteAuditInfo([FromRoute] int id)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var auditInfo = await _context.AuditInfo.FindAsync(id);
        if (auditInfo == null)
        {
            return NotFound();
        }

        _context.AuditInfo.Remove(auditInfo);
        await _context.SaveChangesAsync();

        return Ok(auditInfo);
    }

    private bool AuditInfoExists(int id)
    {
        return _context.AuditInfo.Any(e => e.Id == id);
    }
}

However i got return null for the item related data, how can i fix it? i am new to this framework, any help would appreciate, thanks.

[{"id":1,"level":"level1","period":"jan","auditor":"A","items":null},{"id":2,"level":"level2","period":"feb","auditor":"B","items":null}]

expected output:

[{"id":1,"level":"level1","period":"jan","auditor":"A","items":{"Id":1,"Ponumber":"0001","IsComplete":"True","AuditInfoId":1},{"id":2,"Ponumber":"0002","IsComplete":"True","AuditInfoId":1}}]

To who have similar problem, I solve it by adding

services.AddMvc()
.AddJsonOptions(options => {
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

and edit controller

public async Task<List<AuditInfo>> GetAuditInfo()
    {
        //return _context.AuditInfo;
        var infoes = await _context.AuditInfo.Include(a => a.Items).ToListAsync();
        return infoes;

    }

1 Answer 1

3

I'm not sure if you've seen the accepted answer to this question, but the problem is to do with how the JSON Serializer deals with circular references. Full details and links to more references can be found at the above link, and I'd suggest digging into those, but in short, adding the following to startup.cs will configure the serializer to ignore circular references:

services.AddMvc()
    .AddJsonOptions(options => {
        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    });
Sign up to request clarification or add additional context in comments.

1 Comment

This is exactly correct answer, unbelievable easy to solve. @Hossein You make my day!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.