Search code examples
c#jqueryasp.net-coreasp.net-ajax

Problem in passing a form with input fields and table data from view to controller in ASP.NET Core using jQuery Ajax


I have a form designed in ASP.NET Core, which contains input text fields, dropdowns and also a table where the user can list their past history of distributorship for various companies. Now I want to pass this form data from the view to controller using Ajax.

I have created a model class which will collect the data as an object in the controller. My form input text fields data is getting sent to the controller, but the table data is not showing in the controller section.

I have tried different method to list the table data using resources from the internet. I have listed the table data in an array and tried to pass the array to the controller, but its always a null. I know this is a peculiar problem, because the same logic is working on MVC, but not working on ASP.NET Core. Please help me with the issue, may be I am missing something here.

Here is my code - model class (placed in service layer):

public class RDSSuperProfileVM
{
    public string principalCo { get; set; }
    public string nameOfProp1 { get; set; }
    public string nameOfProp2 { get; set; }
    public string residenceAddress1 { get; set; }
    public string residenceAddress2 { get; set; }
    public string contactNo1 { get; set; }
    public string contactNo2 { get; set; }
    public string emailAddress { get; set; }

    public List<RDS_Distributors> distributorsList { get; set; }
}

public class RDS_Distributors
{
     public string distributorForCompany { get; set; }
     public string dateOfAppointment { get; set; }
     public string currentAvgMonthlyBusiness { get; set; }
     public string paymentTerm { get; set; }
     public string nofRoutes { get; set; }
     public string nofOutlets { get; set; }
}

View.cs:

<form role="form" class="parsley-examples" id="materialForm">
    <div class="form-group row">
        <div class="col-sm-6">
            <!-- text input -->
            <div class="form-group">
                <label>Principal Co. </label>
                <input type="text" required class="form-control" name="principalCo" placeholder="Principal Company" id="principalCo">
            </div>
        </div>
        <div class="col-sm-6">
            <!-- text input -->
            <div class="form-group">
                <label>Email Address:</label>
                <input type="email" required class="form-control" name="emailAddress" placeholder="Email Address" id="emailAddress">
            </div>
        </div>
    </div>
     
    <div class="form-group row">
        <div class="col-sm-6">
            <!-- text input -->
            <div class="form-group">
                <label>Name of Propreiter/Partner/Director 1:</label>
                <input type="text" required class="form-control" name="nameOfProp1" placeholder="Name of Propreiter/Partner/Director 1" id="nameOfProp1">
            </div>
        </div>
        <div class="col-sm-6">
            <!-- text input -->
            <div class="form-group">
                <label>Name of Propreiter/Partner/Director 2:</label>
                <input type="text" required class="form-control" name="nameOfProp2" placeholder="Name of Propreiter/Partner/Director 1" id="nameOfProp2">
            </div>
        </div>
    </div>
    <div class="form-group row">
        <div class="col-sm-6">
            <label for="hori-pass1" class="col-6 col-form-label">Residence Address 1 </label>
            <div class="col-6">
                <textarea class="form-control" rows="3" placeholder="Enter Residence Address" id="residenceAddress1" name="residenceAddress1"></textarea>
            </div>
        </div>
        <div class="col-sm-6">
            <label for="hori-pass1" class="col-6 col-form-label">Residence Address 2 </label>
            <div class="col-10">
                <textarea class="form-control" rows="3" placeholder="Enter Residence Address" id="residenceAddress2" name="residenceAddress2"></textarea>
            </div>
        </div>
    </div>
    <div class="form-group row">
        <div class="col-sm-6">
            <!-- text input -->
            <div class="form-group">
                <label>Contact Number 1:</label>
                <input type="text" required class="form-control" name="contactNo1" placeholder="Contact Number 1" id="contactNo1">
            </div>
        </div>
        <div class="col-sm-6">
            <!-- text input -->
            <div class="form-group">
                <label>Contact Number 2:</label>
                <input type="text" required class="form-control" name="contactNo2" placeholder="Contact Number 2" id="contactNo2">
            </div>
        </div>
    </div>
    <div class="form-group row">
        <div class="card">
    <div class="card-header">
        <h3 class="card-title">CURRENT BUSINESS DETAILS</h3>
    </div>

    <!-- /.card-header -->
    <div class="card-body">
        <table class="table table-bordered table-striped" id="tblDistributors">
            <thead>
                <tr>
                    <th>Distributor for Companies</th>
                    <th>Date of Appoint.</th>
                    <th>Current Avg. Monthly Business</th>
                    <th>Payment Term</th>
                    <th>No. of Routes / Subs</th>
                    <th>No. of Outlets</th>
                    <th>
                        <button type="button" class="btn btn-sm btn-success" onclick="BtnDistributorAdd()">+</button>
                    </th>
                </tr>
            </thead>
            <tbody id="tbodyDistributor">
                <tr id="trowDistributor" class="d-none">                  
                    <td> <input type="text" class="form-control" name="distributorForCompany" placeholder="Distributor for Company" id="distributorForCompany"></td>
                    <td> <input type="date" class="form-control" name="dateOfAppointment" placeholder="Date of Appointment" id="dateOfAppointment"></td>
                    <td> <input type="number" step="0.1" min="0" class="form-control" name="currentAvgMonthlyBusiness" placeholder="Current Avg Business" id="currentAvgMonthlyBusiness"></td>
                    <td> <input type="text" class="form-control" name="paymentTerm" placeholder="Payment Terms" id="paymentTerm"></td>
                    <td> <input type="text" class="form-control" name="nofRoutes" placeholder="Nof Routes" id="nofRoutes"></td>
                    <td> <input type="text" class="form-control" name="nofOutlets" placeholder="Nof Outlets" id="nofOutlets"></td>
                    <td class="NoPrint"><button type="button" class="btn btn-sm btn-danger" onclick="BtnDel(this)">X</button></td>
                </tr>
            </tbody>
        </table>
    </div>
    <!-- /.card-body -->
</div>
</div>

    <div class="form-group row">
        <div class="col-8 offset-4">
            <button type="button" id="btnSave" class="btn btn-primary waves-effect waves-light mr-1">
                Submit
            </button>
            <button type="reset" id="btnCancel"
                    class="btn btn-secondary waves-effect">
                Cancel
            </button>
        </div>
    </div>
</form>
<script>

$("#btnSave").click(function () {
    var distributorData = [];

    $('#tblDistributors > tbody  > tr').each(function (ind, val) {
        if (ind > 0) {
            var distributors = 
                        {
                         "distributorForCompany": $(val).find("input[name='distributorForCompany']").val(),
                        "dateOfAppointment": $(val).find("input[name='dateOfAppointment']").val(),
                        "currentAvgMonthlyBusiness": $(val).find("input[name='currentAvgMonthlyBusiness']").val(),
                        "paymentTerm": $(val).find("input[name='paymentTerm']").val(),
                        "nofRoutes": $(val).find("input[name='nofRoutes']").val(),
                        "nofOutlets": $(val).find("input[name='nofOutlets']").val()
                            };
                    distributorData.push(distributors);
                }
            });

    console.log(distributorData);

    $.ajax({
        type: "POST",
        url: "/RDSuperProfile/GetData",
        data: JSON.stringify(distributorData),
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (r) {
        },
        error: function (response) {
            alert(response.responseText);
        }
    });
})
</script>

Controller:

public JsonResult GetData(List<RDS_Distributors> distributorData)
{
    return Json("Success");
}

I tried to get the data in the controller using List<RDS_Distributors> and List<string>. I'm not receiving the data with either approach. Attaching few screenshots of my table data, the data structured in to an array in Console.Log and the controller POST method where the data received is null.

enter image description here

enter image description here

enter image description here

It will be great if the table data can be sent along with the other form input field's data, else I will use a separate parameter to get the table data and the form serialize data.

Please help as I am confused why the table data is not reaching the controller.


Solution

  • Inside asp.net core MVC, the default model binding is the FromForm which means the will not auto bind the json format request.

    I suggest you could modify your codes to use FromBody like below and then the model binding will work well.

        [HttpPost]
        public JsonResult GetData([FromBody]List<RDS_Distributors> distributorData)
        {
            return Json("Success");
        }
    

    More details, you could refer to below sample:

    View:

    <table id="tblDistributors">
        <thead>
            <tr>
                <th>Distributor For Company</th>
                <th>Date Of Appointment</th>
                <th>Current Avg Monthly Business</th>
                <th>Payment Term</th>
                <th>No. of Routes</th>
                <th>No. of Outlets</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td><input name="distributorForCompany" type="text" value="Company A"></td>
                <td><input name="dateOfAppointment" type="date" value="2024-01-01"></td>
                <td><input name="currentAvgMonthlyBusiness" type="number" value="10000"></td>
                <td><input name="paymentTerm" type="text" value="Net 30"></td>
                <td><input name="nofRoutes" type="number" value="5"></td>
                <td><input name="nofOutlets" type="number" value="20"></td>
            </tr>
            <tr>
                <td><input name="distributorForCompany" type="text" value="Company B"></td>
                <td><input name="dateOfAppointment" type="date" value="2024-02-01"></td>
                <td><input name="currentAvgMonthlyBusiness" type="number" value="15000"></td>
                <td><input name="paymentTerm" type="text" value="Net 60"></td>
                <td><input name="nofRoutes" type="number" value="10"></td>
                <td><input name="nofOutlets" type="number" value="50"></td>
            </tr>
        </tbody>
    </table>
    <button id="btnSave">Save</button>
    
    
     @section Scripts{
     
         <script>
                     $("#btnSave").click(function () {
                var distributorData = [];
    
                $('#tblDistributors > tbody  > tr').each(function (ind, val) {
                    if (val != null)
                    {
                        console.log(ind)
                        var distributors =
                                    {
                                     "distributorForCompany": $(val).find("input[name='distributorForCompany']").val(),
                                    "dateOfAppointment": $(val).find("input[name='dateOfAppointment']").val(),
                                    "currentAvgMonthlyBusiness": $(val).find("input[name='currentAvgMonthlyBusiness']").val(),
                                    "paymentTerm": $(val).find("input[name='paymentTerm']").val(),
                                    "nofRoutes": $(val).find("input[name='nofRoutes']").val(),
                                    "nofOutlets": $(val).find("input[name='nofOutlets']").val()
                                        };
                                distributorData.push(distributors);
                            }
                        });
    
                console.log(distributorData);
    
                $.ajax({
                    type: "POST",
                    url: "/RDSuperProfile/GetData",
                    data: JSON.stringify(distributorData),
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (r) {
                    },
                    error: function (response) {
                        alert(response.responseText);
                    }
                });
            })
        </script>
         </script>
     }
    

    Controller:

    public class RDSuperProfileController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    
        [HttpPost]
        public JsonResult GetData([FromBody]List<RDS_Distributors> distributorData)
        {
            return Json("Success");
        }
    }
    

    Result:

    enter image description here