Here is a working demo:
Model:
public class TestCheckBox {
public IList<SelectListItem> SelectedCases { get; set; } = new List<SelectListItem>();
[DisplayName("Available Cases")]
public IList<SelectListItem> AvailableCases { get; set; } = new List<SelectListItem>();
}
Controller:
[HttpGet]
public IActionResult TestBindCheckBox() {
TestCheckBox t = new TestCheckBox { AvailableCases = new List<SelectListItem> { new SelectListItem { Text = "one" }, new SelectListItem { Text = "two" }, new SelectListItem { Text = "three" } } };
return View(t);
}
[HttpPost]
public IActionResult TestBindCheckBox(TestCheckBox testCheckBox)
{
return Ok();
}
CheckBox.cs(ViewComponent):
public class CheckBox:ViewComponent
{
public async Task<IViewComponentResult> InvokeAsync(TestCheckBox t)
{
return View(t);
}
}
Pages/Shared/CheckBox/Default.cshtml:
<form method="post" id="myForm">
@for (int i = 0; i < Model.AvailableCases.Count(); i++)
{
<br />
<input type="checkbox" asp-for="@Model.AvailableCases[i].Selected" />
<input hidden asp-for="@Model.AvailableCases[i].Text" />
<label asp-for="@Model.AvailableCases[i].Selected">@Model.AvailableCases[i].Text</label>
}
<input type="submit" />
</form>
TestBindCheckBox:
@await Component.InvokeAsync("CheckBox", @Model)
@section Scripts {
<script>
$('#myForm').submit(function () {
var count = 0;
$(":checkbox:checked").each(function () {
$(this).attr("name", "SelectedCases[" + count + "].Selected");
$(this).next("input").attr("name", "SelectedCases[" + count + "].Text");
count++;
})
return true; // return false to cancel form action
});
</script>
}
result:

Update:
If you are using ViewComponent,only need to use