'Controller not able to bind form array to model

I have this in my cshtml:

        <div class="row checkbox-group">
            @foreach (var category in Model._categories)
            {
                <div class="col-12 col-sm-6 col-md-4 col-lg-3" data-toggle="tooltip" data-placement="top" title="@category.Description">
                    <input type="checkbox" name="ChosenCategories[]" value="@category.Id" id="[email protected]" />
                    <label class=" btn btn-flat" for="[email protected]">
                        <i class="material-icons-round">
                            @category.Icon
                        </i>@category.Name
                    </label>
                </div>
            }
        </div>

Using serializeArray to send data

formData = $('form').serializeArray();

I can confirm that data is sent like this in the console.

0: {name: 'ChosenCategories[]', value: '1005'}
1: {name: 'ChosenCategories[]', value: '1006'}
2: {name: 'ChosenCategories[]', value: '1009'}
3: {name: 'ChosenCategories[]', value: '1010'}

But in the controller the model binding and the Request.Form["ChosenCategories"] is also empty.

The important part of the model is like this:

    public partial class MyClass
    {
        public MyClass()
        {
            ChosenCategories = new HashSet<ChosenCategories >();
        }
        public virtual ICollection<ChosenCategories > ChosenCategories { get; set; }
    }

I am trying to bind ChosenCategories[] to my model, but it is not working. The data in the controller(Request.Form["ChosenCategories"]) comes out blank. What am I doing wrong?



Solution 1:[1]

Here is a demo to pass an array to action with ajax:

view:

<div class="row checkbox-group">
            @{var i=0;}
            @foreach (var category in Model._categories)
            {
                <div class="col-12 col-sm-6 col-md-4 col-lg-3" data-toggle="tooltip" data-placement="top" title="@category.Description">
                    <input type="checkbox" name="ChosenCategories[@i]" value="@category.Id" id="[email protected]" />
                    <label class=" btn btn-flat" for="[email protected]">
                        <i class="material-icons-round">
                            @category.Icon
                        </i>@category.Name
                    </label>
                </div>
                i++;
            }
        </div>

So that your array will be:

0: {name: 'ChosenCategories[0]', value: '1005'}
1: {name: 'ChosenCategories[1]', value: '1006'}
2: {name: 'ChosenCategories[2]', value: '1009'}
3: {name: 'ChosenCategories[3]', value: '1010'}

ajax(If you want to pass array in ajax,you need to use json type data):

function test() {
            var s = $("#test").serializeArray();
            $.ajax({
                url: "Test",
                type: 'post',
                data: JSON.stringify(s),
                contentType: "application/json",
                success: function (response) {

                    //end of Ajax
                }
            });
        }

action:

public IActionResult Test([FromBody]List<Category> l)
        {
            return View();
        }

Category:

public class Category {
        public int value { get; set; }
        public string name { get; set; }

    }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yiyi You