0

I am building a simple to-do list api using ASP.Net Core. It has two main two main models, a List model and a Task model. Each List has many Tasks. I build the models like this:

List Model:

namespace ToDoList.Models
{
    public class List
    {
        [Key]
        public int ListId { get; set; }
        [Required]
        [StringLength(25)]
        public string Title { get; set; }
        public string Colour { get; set; }
        public virtual ICollection<Task> Tasks { get; set; }

        public List()
        {
            Tasks = new List<Task>();
            Colour = "secondary";
        }
    }
}

Task Model:

namespace ToDoList.Models
{
    public class Task
    {
        [Key]
        public int TaskId { get; set; }
        [Required]
        [StringLength(50)]
        public string Title { get; set; }
        public bool Done { get; set; }
        public int ListId { get; set; }
        public virtual List List { get; set; }

        public Task()
        {
            Done = false;
        }
    }
}

When I send a post request to create a new task I am struggling to get the created task to be added to the Icollection part of the List model.

My Controller looks like this:

// POST: api/Tasks
        [HttpPost]
        public async Task<ActionResult<Models.Task>> PostTask(Models.Task task)
        {
            _context.Tasks.Add(task);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetTask", new { id = task.TaskId }, task);
        }

If I send this data as JSON as a POST request:

{ title: "A New Task", listId: 11 }

I create this Task:

{"taskId":16,"title":"A New Task","done":false,"listId":11,"list":null}

As you can see it has the right listId but the list attached is null.

Also the task does not get added to the list.Tasks collection.

{"listId":11,"title":"Learn ASP.Net Core","colour":"secondary","tasks":[]}

As you can see tasks is still empty.

How do I get it set up that when ever a task is created it is always add to List.Tasks and then Tasks.List has the correct list attached to it, not null.

Also On my SQL Sever Database I expected to see a Tasks in the Lists table but I don't. Can anyone explain why? SQL Sever Database Columns Picture

RJGMorris
  • 29
  • 1
  • 8

1 Answers1

1

You could load the List entity from your DbContext and add it to the Task object you are returning:

[HttpPost]
public async Task<ActionResult<Models.Task>> PostTask(Models.Task task)
{
    _context.Tasks.Add(task);
    await _context.SaveChangesAsync();

    task.List = _context.Lists.Single(task.ListId);
    return CreatedAtAction("GetTask", new { id = task.TaskId }, task);
}

or you could return an instance of the Task loaded from the DbContext with included List:

var taskFromDb = _context.Tasks.Include(x => x.List).Single(x => x.Id = task.Id);
return CreatedAtAction("GetTask", new { id = task.TaskId }, taskFromDb);

To get a list with tasks, it needs to be loaded from the DbContext:

var listWithTasks = _context.Lists.Include(x => x.Tasks).Single(x => x.Id == task.ListId);
Martin Staufcik
  • 8,295
  • 4
  • 44
  • 63
  • Okay I think i'm getting some where but am now getting an object cycle exception "JsonException: A possible object cycle was detected which is not supported. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 32." Any idea of to fix? – RJGMorris Apr 09 '20 at 10:50
  • I Have solved the Cycle problem by following this thread https://stackoverflow.com/questions/59199593/net-core-3-0-possible-object-cycle-was-detected-which-is-not-supported – RJGMorris Apr 09 '20 at 11:04