I have an application that shows a checklist with a dynamic list of tasks. For now all the tasks have 2 radio buttons: one for Done and one for Not Done. I will be adding new task types (textboxes etc.) later.
The main view calls an editor template that creates each task. The checklist model keeps the tasks in a property "Tasks" of type List<Task>
. This is fine for display, but has trouble on form submit.
I want to have each task save independently, so I have placed a <form>
element around the controls in the editor template.
Controller
public class CheckController : Controller
{
[HttpGet]
public ActionResult Index()
{
var checklist = new Checklist();
GetData(checklist);
return View(checklist);
}
[HttpPost]
public ActionResult Index(Task model)
{
var task = (Task)model;
return Content($"Save Task:{task.TaskId} Value:{task.IsDone}");
}
}
Models
public class Checklist
{
public List<Task> Tasks { get; set; }
public Checklist()
{
Tasks = new List<Task>();
}
}
public class Task
{
public int TaskId { get; set; }
public string TaskName { get; set; }
public bool IsDone { get; set; }
}
Views
@model Checkpoint.Models.Checklist
<table>
@Html.EditorFor(x => x.Tasks);
</table>
@model Checkpoint.Models.Task
<tr>
<td>@Model.TaskName</td>
<td data-ftid="@Model.TaskId">
@{
using (Html.BeginForm("Index", "Check", FormMethod.Post))
{
@Html.HiddenFor(x => x.TaskId)
@Html.RadioButtonFor(x => x.IsDone, false)<span>Incomplete</span>
@Html.RadioButtonFor(x => x.IsDone, true)<span>Complete</span>
<button role="button" type="submit" name="taskAction">Submit</button>
}
}
</td>
</tr>
Rendered HTML
<tr>
<td>First thing</td>
<td>
<form action="/Checklist" method="post">
<input id="Tasks_0__TaskId" name="Tasks[0].TaskId" type="hidden" value="1" />
<input checked="checked"id="Tasks_0__IsDone" name="Tasks[0].IsDone" type="radio" value="False" />
<span>Incomplete</span>
<input id="Tasks_0__IsDone" name="Tasks[0].IsDone" type="radio" value="True"
<span>Complete</span>
<button role="button" type="submit" name="taskAction">Submit</button>
</form>
</td>
</tr>
<tr>
<td>Second thing</td>
<td>
<form action="/Checklist" method="post">
<input id="Tasks_1__TaskId" name="Tasks[1].TaskId" type="hidden" value="2" />
<input checked="checked" id="Tasks_1__IsDone" name="Tasks[1].IsDone" type="radio" value="False" />
<span>Incomplete</span>
<input id="Tasks_1__IsDone" name="Tasks[1].IsDone" type="radio" value="True" />
<span>Complete</span>
<button role="button" type="submit" name="taskAction">Submit</button>
</form>
</td>
</tr>
This does submit the request, but the data looks like this:
Tasks[1].TaskId: 1
Tasks[1].IsDone: True
When it reaches the controller action (which accepts type Task), the property values are null.
How can I get my task data correctly in the controller action? Or am I going about this in the totally wrong way?
Bonus: what would be the best approach for adding the new task types?