How to post a list in asp.net core mvc?

Alick Wang 306 Reputation points
2023-03-13T13:39:58.9066667+00:00

In the web page,the user may add many item dynamically,the items‘ number is not fixed.How can I post the items to the add action?

model.cs

class vm

{

int departmentID;

List<employee> employee;

}

class emloyee{

string name;

int age;

}

.chtml

@model vm

.............

<p> departmentID</p>

<input asp-for="departmentID">

<p> emplyee item</p>

<input asp-for="employee.name"><input asp-for="employee.age">

<input asp-for="employee.name"><input asp-for="employee.age">

<input asp-for="employee.name"><input asp-for="employee.age">

.............................

ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,815 questions
0 comments No comments
{count} votes

Accepted answer
  1. Zhi Lv - MSFT 33,191 Reputation points Microsoft External Staff
    2023-03-15T08:25:17.35+00:00

    Hi @Alick Wang

    There is a problem. If I add a button so that client can remove the <tr> as he want ,then this code : name='employee[" + count + "].name' ,count maybe not be continuous,does if matter?

    After testing, it seems that if remove the tr and the count is not continuous, when click the submit button we can only receive part of data in the controller.

    For example, the name are: employee[0].name, employee[2].name, in the controller, we can only receive the value from employee[0].name.

    So, if you want to remove the tr, you have to loop through the rows and change the count to continuous. or you can try to use JQuery Ajax to submit the data: loop through the rows and create JavaScript object, then submit the data to the controller.

    I create a sample with the remove tr function and submit the data via JQuery ajax, you can refer to it:

    @model WebApplication5.Models.vm
    
    @{
        ViewData["Title"] = "AddEmployeeView";
    }
    
    <h1>AddEmployeeView</h1>
    
    <h4>vm</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="AddEmployeeView">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="departmentID" class="control-label"></label>
                    <input asp-for="departmentID" class="form-control" />
                </div>
                <div class="form-group">
                    <table id="tbemployee">
                        <thead>
                            <tr>
                                <td>Name</td>
                                <td>Age</td>
                                <td>Action</td>
                            </tr>
                        </thead>
                        <tbody class="table" id="tbbody">
                            @if (Model == null || Model.employee == null || Model.employee.Count == 0)
                            {
                                <tr>
                                    <td>
                                        <input class="form-control" id="name" name="employee[0].name" />
                                    </td>
                                    <td>
                                        <input class="form-control" id="age" name="employee[0].age" />
                                    </td>
                                    <td><input type="button" class="btnremove" value="remove"/></td>
                                </tr>
                            }
                            else if (Model.employee != null && Model.employee.Count > 0)
                            {
                                @for (var i = 0; i < Model.employee.Count; i++)
                                {
    
                                    <tr>
                                        <td>
                                            <input class="form-control" asp-for="@Model.employee[@i].name" />
                                        </td>
                                        <td>
                                            <input class="form-control" asp-for="@Model.employee[@i].age" />
                                        </td>
                                        <td></td>
                                    </tr>
                                }
                            }
                        </tbody>
                        <tfoot>
                            <tr>
                                <td colspan="2"><input type="button" id="btnAddNew" value="Add New Employee" class="btn btn-primary" /></td>
                                <td><input type="button" id="btnAjaxSubmit" value="Submit Via Ajax" class="btn btn-primary" /></td>
                            </tr>
    
                        </tfoot>
                    </table>
                </div>
                <div class="form-group">
                    <input type="submit" value="Submit" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
    
    @section Scripts {
        @{
            await Html.RenderPartialAsync("_ValidationScriptsPartial");
        }
    
        <script>
            $(function () {
                $("#btnAddNew").click(function () {
                    var count = $("#tbbody >tr").length;
                    $("#tbbody").append("<tr><td> <input class='form-control' id='name' name='employee[" + count + "].name'></td><td> <input class='form-control' id='age' name='employee[" + count + "].age'></td> <td><input type='button' class='btnremove' value='remove'/></td></tr>");
    
                    AddRemoveAction();
                });
    
                
                AddRemoveAction();
    
                //add remove button click event
                function AddRemoveAction(){ 
                    $(".btnremove").each(function(index, item){
                        $(item).click(function(){
                            $(this).closest('tr').remove();
                        });
                
                    })
                }
                //use Ajax to submit the data
                $("#btnAjaxSubmit").click(function(){ 
                    //define a object.
                    var vm = {};
                    vm.departmentID = parseInt($("#departmentID").val());
    
                    var employees = [];
                    //loop through the rows and get the name and age.
                    $("#tbbody >tr").each(function(index, item){
                        var newemp = {};
                        newemp.name = $(item).find("#name").val();
                        newemp.age = parseInt($(item).find("#age").val());
                        employees.push(newemp);
                    });
                    vm.employee = employees;
                    //use jquery ajax to call the controller action.
                    $.ajax({
                        type: "POST",
                        url: "/Home/AddEmployeeView",
                        dataType: "json",
                        contentType: 'application/json',
                        headers: {
                            RequestVerificationToken:
                                $('input:hidden[name="__RequestVerificationToken"]').val()
                        },
                        data: JSON.stringify(vm),
                        success: function (data) {
    
                            //in the success function, you can redirect to other page via the windows.location property.
                            alert(data);
                        }
                    });
                });
    
            });
        </script>
    }
    
    

    Controller:

            public IActionResult AddEmployeeView()
            { 
                //var vm = new vm()
                //{
                //    departmentID=1001,
                //    employee = new List<employee>()
                //    {
                //        new employee(){ name="A", age=21 },
                //        new employee(){ name="B", age=22 },
                //    }
                //};
                //return View(vm);
                return View();
            }
            [HttpPost]
            public IActionResult AddEmployeeView([FromBody] vm vm)
            {
                return View();
            }
    

    The result as below:

    image1


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Dillion

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Zhi Lv - MSFT 33,191 Reputation points Microsoft External Staff
    2023-03-14T05:30:33.79+00:00

    Hi @Alick Wang

    You can refer to the following sample code:

    class:

        public class vm
        {
            public int departmentID { get; set; }
    
            public List<employee> employee { get; set; }
        }
        public class employee
        {
            public string name { get; set; }
            public int age { get; set; }
        }
    

    Controller:

            public IActionResult AddEmployee()
            {
                //return a view with initial vm model.
                //var vm = new vm()
                //{
                //    departmentID=1001,
                //    employee = new List<employee>()
                //    {
                //        new employee(){ name="A", age=21 },
                //        new employee(){ name="B", age=22 },
                //    }
                //};
                //return View(vm);
    
                //return an empty view.
                return View();
            }
            [HttpPost]
            public IActionResult AddEmployee(vm vm)
            {
                return View();
            }
    

    View page: use if-else statement to check whether the employee has items, if not add one row to enter the new employee; if the employee has items use a for loop to display the employees. After that click the "Add New Employee" button to add new row dynamically:

    @model WebApplication5.Models.vm
    
    @{
        ViewData["Title"] = "AddEmployee";
    }
    
    <h1>AddEmployee</h1>
    
    <h4>vm</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="AddEmployee">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="departmentID" class="control-label"></label>
                    <input asp-for="departmentID" class="form-control" /> 
                </div>
                <div class="form-group"> 
                    <table id="tbemployee" >
                        <thead>
                            <tr>
                                <td>Name</td>
                                <td>Age</td>
                            </tr> 
                        </thead>
                        <tbody class="table" id="tbbody">
                            @if (Model == null || Model.employee == null || Model.employee.Count == 0)
                            {
                                <tr>
                                    <td>
                                        <input class="form-control" name="employee[0].name"/>
                                    </td>
                                    <td>
                                        <input class="form-control" name="employee[0].age"/>
                                    </td>
                                </tr>
                            }
                            else if (Model.employee != null && Model.employee.Count > 0)
                            {
                                @for (var i = 0; i < Model.employee.Count; i++)
                                {
    
                                    <tr>
                                        <td>
                                            <input class="form-control" asp-for="@Model.employee[@i].name" />
                                        </td>
                                        <td>
                                            <input class="form-control" asp-for="@Model.employee[@i].age" />
                                        </td>
                                    </tr>
                                }
                            }
                        </tbody>
                        <tfoot>
                            <tr><td colspan="2"><input type="button" id="btnAddNew" value="Add New Employee" class="btn btn-primary" /></td></tr> 
                        </tfoot>
                    </table>
                </div> 
                <div class="form-group">
                    <input type="submit" value="Submit" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
    
    @section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    
        <script>
            $(function(){
                $("#btnAddNew").click(function(){
                    var count = $("#tbbody >tr").length;
                    $("#tbbody").append("<tr><td> <input class='form-control' name='employee[" + count + "].name'></td><td> <input class='form-control' name='employee[" + count + "].age'></td></tr>");
                });
            });
        </script>
    }
    
    

    The result as below:

    return an empty view:

    image1

    return a vm model:

    image2


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best regards,

    Dillion

    1 person found this answer helpful.

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.