简体   繁体   中英

Passing array of objects to Controller Action using jQuery ajax request using .NET Core 2.2 doesn't work

Array of objects after stringifying is not passed to controller action and the parameter of action (the model) is null .

I have tried many solutions given to this problem in StackOverflow but none of these solution solved my problem. I provided the links which I tried:

Pass array to mvc Action via AJAX

pass array in javascript object to mvc controller

Here is my code

JavaScript Code

$("#FormSubmit").click(function () {
    var datalist = [];

    $("#MarksTable tbody tr").each(function () {

        var obj = {};
        obj.StudentID = 1;
        obj.ExamTimeTableID = 1;
        obj.ClassActivity = $(this).find("td:eq(5) input").val();
        obj.IsPresent = $(this).find("td:eq(7) input").val();
        obj.Assignment = $(this).find("td:eq(6) input").val();
        obj.MidTerm = $(this).find("td:eq(3) input").val();
        obj.Final = $(this).find("td:eq(4) input").val();

        datalist.push(obj);
    });

    $.ajax({
        url: "@Url.Action("InsertData", "Examination")",
        type: "POST",
        cache: false,
        contentType: "application/json;charset=utf-8",
        dataType: "json",
        data: JSON.stringify(datalist),
        success: function (result) {
            alert(result);
        },
        error: function (errormessage) {
            alert(errormessage.responseText);
        }
    });
});

Action of Controller:

[HttpPost]
public JsonResult InsertData([FromBody] List<StudentMarksList> obj)
{

    DynamicParameters param = new DynamicParameters();
    .
    .
    .
    return Json(param.Get<string>("msg"));
}

The Model:

public class StudentMarksList
{
    public int StudentID { get; set; }
    public int ExamTimeTableID { get; set; }
    public int ClassActivity { get; set; }
    public int IsPresent { get; set; }
    public int Assignment { get; set; }
    public int MidTerm { get; set; }
    public int Final { get; set; }
}

Request Payload:

[,…]
0: {StudentID: 1, ExamTimeTableID: 1, ClassActivity: 3, IsPresent: 0, Assignment: 2, MidTerm: 5, Final: 4}
Assignment: 2
ClassActivity: 3
ExamTimeTableID: 1
Final: 4
IsPresent: 0
MidTerm: 5
StudentID: 1

Request Payload source:

[{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":3,"IsPresent":0,"Assignment":2,"MidTerm":5,"Final":4}]

The obj should contains the passed objects but it is null .

Any Help???

[Edit] Change the js as below:

    function toInt(str){
        var i = parseInt(str);
        return i ? i : 0;
    }

    $("#MarksTable tbody tr").each(function () {

        var obj = {};
        obj.StudentID = 1;
        obj.ExamTimeTableID = 1;
        obj.ClassActivity = toInt( $(this).find("td:eq(5) input").val());
        obj.IsPresent =toInt(  $(this).find("td:eq(7) input").val());
        obj.Assignment = toInt( $(this).find("td:eq(6) input").val());
        obj.MidTerm =toInt(  $(this).find("td:eq(3) input").val());
        obj.Final = toInt( $(this).find("td:eq(4) input").val());

        datalist.push(obj);
    });

This will make sure the empty input to 0 instead of null .


That's because on your server side you're declaring the ClassActivity / ClassActivity / Assignment /... as int type but your js send all them as string . For example, the Payload sent to server will be something like:

 [{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":"3","Assignment":"aa","MidTerm":"333333333","Final":"3333"},{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":"","Assignment":"s","MidTerm":"2","Final":"1"},{"StudentID":1,"ExamTimeTableID":1,"ClassActivity":"3","Assignment":"","MidTerm":"2","Final":"1"}]

Please either change the property type or convert the $(this).find("td:eq(7) input").val() result (a string ) to int / bool /... type before sending them.

You can try this also.

cshtml page you need to add one form tag like eg.

<div style="display:none;">
<form id="FormPost"></form>
</div>

Jquery Code

$("#FormSubmit").click(function () {

    $("#FormPost").html('');
    $("#MarksTable tbody tr").each(function (index,elem) {

       addHidden("StudentID["+index+"]","1");
       addHidden("ExamTimeTableID["+index+"]","1");
       addHidden("ClassActivity["+index+"]",$(this).find("td:eq(5) input").val());
       addHidden("IsPresent["+index+"]",$(this).find("td:eq(7) input").val());
       addHidden("Assignment["+index+"]",$(this).find("td:eq(6) input").val());
       addHidden("MidTerm["+index+"]",$(this).find("td:eq(3) input").val());
       addHidden("Final["+index+"]",$(this).find("td:eq(4) input").val());
    });

    $.ajax({
        url: "@Url.Action("InsertData", "Examination")",
        type: "POST",
        cache: false,
        contentType: "application/json;charset=utf-8",
        dataType: "json",
        data: $("#FormPost").serialize(),
        success: function (result) {
            alert(result);
        },
        error: function (errormessage) {
            alert(errormessage.responseText);
        }
    });
});

function addHidden(key, value) {   
    var input = document.createElement('input');
    input.type = 'hidden';
    input.name = key;
    input.value = value;
    $("#FormPost").appendChild(input);
}

Action of Controller:

[HttpPost]
public JsonResult InsertData(List<StudentMarksList> obj)
{

    DynamicParameters param = new DynamicParameters();
    .
    .
    .
    return Json(param.Get<string>("msg"));
}

That could be dynamic value of one of property in object below is not a number, it contains some alphabet characters.

var obj = {};
        obj.StudentID = 1;
        obj.ExamTimeTableID = 1;
        obj.ClassActivity = $(this).find("td:eq(5) input").val();//this value could be not a number, ex: 'abc' text
        obj.IsPresent = $(this).find("td:eq(7) input").val();
        obj.Assignment = $(this).find("td:eq(6) input").val();
        obj.MidTerm = $(this).find("td:eq(3) input").val();
        obj.Final = $(this).find("td:eq(4) input").val();

It will be reason that Asp.Net cannot deserialize your action parameter item to object of StudentMarksList.

If above is not the root cause, you can follow this question to log out serialization errors to have further investigation.

Simply add this property to your ajax call:

traditional:true,

such that your ajax call looks like this at the end

$.ajax({
    url: "@Url.Action("InsertData", "Examination")",
    type: "POST",
    cache: false,
    traditional:true,
    contentType: "application/json;charset=utf-8",
    dataType: "json",
    data: JSON.stringify(datalist),
    success: function (result) {
        alert(result);
    },
    error: function (errormessage) {
        alert(errormessage.responseText);
    }
});

Happy coding. Hope it helps someone just as it helped me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM