Against my better judgement, I created an example. This is an example NOT a solution. In production code you would NOT pass entities between the client and Web API! Typically you would designed a data interrace and pass poco classes.
I used followed the following documentation which I have provided many times over many of your threads.
Tutorial: Create a web API with ASP.NET Core
Saving Related Data
Entities
public partial class Developer
{
public int DeveloperId { get; set; }
public List<ActionItem>? ActionItems { get; set; }
}
public class ActionItem
{
public int ActionItemId { get; set; }
public string? Tilte { get; set; }
public string? Description { get; set; }
public string? State { get; set; }
public DateTime? OpenDate { get; set; }
public DateTime? PlanDate { get; set; }
public DateTime? CloseDate { get; set; }
public int DeveloperId { get; set; }
public Developer? Developer { get; set; }
Related data configuration
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ActionItem>()
.HasOne(d => d.Developer)
.WithMany(d => d.ActionItems);
}
Controller
[Route("api/[controller]")]
[ApiController]
public class DeveloperActionController : ControllerBase
{
private readonly WebApiSqliteContext _context;
public DeveloperActionController(WebApiSqliteContext context)
{
_context = context;
}
// GET: api/<DeveloperActionController>
[HttpGet]
public IEnumerable<Developer> GetDevelopersWithActions()
{
return _context.Developers.Include(a => a.ActionItems).ToList();
}
// GET api/<DeveloperActionController>/5
[HttpGet("{id}")]
public async Task<ActionResult<Developer>> GetDeveloperActions(int id)
{
Developer? developer = await _context.Developers
.Include(a => a.ActionItems)
.FirstOrDefaultAsync(d => d.DeveloperId == id);
if (developer == null)
{
return NotFound();
}
return Ok(developer);
}
// POST api/<DeveloperActionController>
[HttpPost]
public async Task<ActionResult<Developer>> PostAsync([FromBody] Developer developer)
{
_context.Developers.Add(developer);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetDeveloperActions), new { id = developer.DeveloperId }, developer);
}
// PUT api/<DeveloperActionController>/5
[HttpPut("{id}")]
public async Task<ActionResult<Developer>> Put(int id, [FromBody] ActionItem actionItem)
{
Developer? developer = await _context.Developers
.Include(a => a.ActionItems)
.FirstOrDefaultAsync(d => d.DeveloperId == id);
if (developer == null)
{
return NotFound();
}
developer.ActionItems.Add(actionItem);
await _context.SaveChangesAsync();
return CreatedAtAction(nameof(GetDeveloperActions), new { id = developer.DeveloperId }, developer);
}
// DELETE api/<DeveloperActionController>/5
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
Developer? developer = await _context.Developers
.Include(a => a.ActionItems)
.FirstOrDefaultAsync(d => d.DeveloperId == id);
if (developer == null)
{
return NotFound();
}
_context.Remove(developer);
await _context.SaveChangesAsync();
return NoContent();
}
}
Post data
{
"developerId": 0,
"actionItems": [
{
"actionItemId": 0,
"tilte": "Action Title",
"description": "Description",
"state": "State",
"openDate": "2022-11-17",
"planDate": "2022-11-17",
"closeDate": "2022-11-17",
"developerId": 0
}
]
}
Put data
{
"actionItemId": 0,
"tilte": "Action Title 2",
"description": "Description 2",
"state": "State 2",
"openDate": "2022-11-18",
"planDate": "2022-11-18",
"closeDate": "2022-11-18",
"developerId": 1
}
Configuration is needed to return a entity otherwise you'll get an error.
builder.Services.AddControllers().AddJsonOptions(x =>
x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles);