Search code examples
c#asp.net-core-mvcrazor-pages

Binding checkBoxList on Razor Page with Viewdata


I want to bind a CheckBoxList on Razor page with Viewdata.I have the following code on my Controller Index:

 public async Task<IActionResult> Index()
 {
var testSections = new List<ReassignmentSectionLookup>();
testSections = await _employeeService.GetTestSections();
 ViewData["testSections"] = new SelectList(testSections, "ReassignmentSectionLookupID", "Section");
return View();
}

I have the following on my razor page:

 <div class="form-group row">

                    <div class="col-md-12">

                        Select Test: <br />
                        @{
                            var select = ViewData["testSections"] as SelectList;
                            if (select != null && select.ToList().Count > 0)
                            {
                                foreach (var item in select.ToList())
                                {
                                    <input type="checkbox" name="selectedItems" value="@item.Value" @(Html.Raw(item.Selected ? "checked=\"checked\"" : "")) /> @item.Text  <br />
                                }
                            }
                        }

                    </div>

When I hover over select, I can see 12 items in the select:

enter image description here

when I hover over select.ToList().Count I get an error saying "system.NullReferenceException". I am not sure what am I doing wrong. I can see the data in the select. below is the screen shot of the error: enter image description here

If I try doing select.Items.ToList() then I am getting this error: enter image description here

When using this line:

<input type="checkbox" name="selectedItems" value="@item.Value" @(Html.Raw(item.Selected ? "checked=\"checked\"" : "")) /> @item.Text  <br />

I am getting this error:

enter image description here


Solution

  • As discussed in the comment, I would say SelectList is not suitable as it is used to render the items for the select/drop-down list with either tag helper (asp-items) or HtmlHelper (@Html.DropdownList()).

    1. Create a model class for the data set.
    public class ReassignmentSectionLookupOption
    {
        public string Text { get; set; }
        public int Value { get; set; }
        public bool Selected { get; set; }
    }
    
    1. Instead of returning the data as SelectList in ViewData, return as List<ReassignmentSectionLookupOption> type.
    public async Task<IActionResult> Index()
    {
        var testSections = await _employeeService.GetTestSections();
     
        ViewData["testSections"] = testSections
            .Select(x => new ReassignmentSectionLookupOption { Value = x.ReassignmentSectionLookupID, Text = x.Section })
            .ToList();
    
        return View();
    }
    
    1. In View, cast the ViewData as List<ReassignmentSectionLookupOption>. And you can use .Any() to check whether the list is not empty.
    @{
        var testSections = ViewData["testSections"] as List<ReassignmentSectionLookupOption>;
        if (testSections != null && testSections.Any())
        {
            foreach (var item in testSections)
            {
                <input type="checkbox" name="selectedItems" value="@item.Value" @(Html.Raw(item.Selected ? "checked=\"checked\"" : "")) /> @item.Text <br />
            }
        }
    }