Home > Back-end >  ASP.NET Core - Controller Not Receiving Full JavaScript Array Object from Ajax
ASP.NET Core - Controller Not Receiving Full JavaScript Array Object from Ajax

Time:10-02

I have a JS Object Array which I am passing in the ajax to the controller. If I pass maximum of 11 objects in the array, controller receives the array but if the objects are more than 11, it receives the array as null. Here is it. enter image description here

In the controller, I will receive the passed employee array as shown below.

enter image description here

But if I pass a big JavaScript array object, its value is null. enter image description here

enter image description here

I have an array of 50 objects. I have tested all of them. The object match the Model properties. There is nothing wrong with the modal.

Please tell me what wrong I am doing here.

Here is my JS code. Basically, I am trying to read a csv file and pushing all the data to javascript array. The javascript array has same properties as the model field names.

let employees = [];
let reader = new FileReader();

$("#btnSave").click(function () {
    Save();
})

$("#file").change(function (e) {
    //getting the uploaded file
    let fileUpload = $("#file").get(0)
    let file = fileUpload.files[0];
    //load the reader
    reader.onloadend = function (evt) {
        let lines = evt.target.result;
        if (lines && lines.length > 0) {
            let allRows = CSVToArray(lines);
            let header = allRows[0];
            let thead = $('thead tr')
            thead.html("")
            let tbody = $('tbody')
            header.forEach(h => thead.append(`<th>${h}</th>`))
            for (let i = 1; i < allRows.length; i  ) {
                tbody.append('<tr>')
                let cellArr = allRows[i];
                let emp = {}
                for (let k = 0; k < cellArr.length; k  ) {
                    emp[allRows[0][k]] = cellArr[k]   "";
                    tbody.append(`<td>${cellArr[k]}</td>`)
                }
                tbody.append('</tr>')
                employees.push(emp)
            }
        }
    }
    reader.readAsBinaryString(file)
})

function CSVToArray(strData, strDelimiter) {
    strDelimiter = (strDelimiter || ",");
    let objPattern = new RegExp(
        (
            "(\\"   strDelimiter   "|\\r?\\n|\\r|^)"  
            "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|"  
            "([^\"\\"   strDelimiter   "\\r\\n]*))"
        ),
        "gi"
    );
    let arrData = [[]];
    let arrMatches = null;

    while (arrMatches = objPattern.exec(strData)) {
        let strMatchedDelimiter = arrMatches[1];
        let strMatchedValue = [];
        if (strMatchedDelimiter.length && (strMatchedDelimiter != strDelimiter)) {
            arrData.push([]);
        }
        if (arrMatches[2]) {
            strMatchedValue = arrMatches[2].replace(new RegExp("\"\"", "g"), "\"");
        } else {
            strMatchedValue = arrMatches[3];
        }
        arrData[arrData.length - 1].push(strMatchedValue);
    }
    return (arrData);
}

function Save() {
    console.log( employees)
    if (employees.length > 0) {
        $.ajax({
            url: '/Master/SaveMaster',
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            data: JSON.stringify(employees),
            success: function (result) {
                /*for (let k = 0; k < result.length; k  ) {
                    $('tbody tr:eq('   (result[k].employeeId - 1)   ')').css('border', '3px solid #dc3545');
                    let props = Object.entries(employees[result[k].employeeId])
                    console.log(result[k])
                    let cellIndex = props.findIndex(p => p[0] === result[k].field)
                    $('tbody tr:eq('   (result[k].employeeId - 1)   ') td:eq('   cellIndex   ')').css({ 'background-color': '#dc3545', 'color': '#ffffff' });
                    $('tbody tr:eq('   (result[k].employeeId - 1)   ') td:eq('   cellIndex   ')').attr("title", result[k].error)
                }
                $(".main-container").append(`
                       <div class="alert alert-success alert-dismissible fade show" role="alert">
                           Data Successfully imported into the database
                       </div>
                    `)*/
            },
            error: function (result) {
                console.log(result)
            }
        })
    }
    else {
        alert("No Data Found.");
    }
}

Here is my controller

        [Route("/Master/SaveMaster")]
        [HttpPost]
        public List<MasterError> SaveMaster(List<MasterData> masterData)
        {
            List<MasterError> masterErrorsList = new List<MasterError>();

            //for(int i = 0; i < masterData.Count(); i  )
            //{
                //Employee employee = new Employee();
                //employee.ArabicName = masterData[i].ArabicName;
                //employee.Code = masterData[i].Code;
                //employee.Email = masterData[i].Email;
                //employee.FirstName = masterData[i].FirstName;
                //employee.LastName = masterData[i].LastName;
                //employee.MiddleName = masterData[i].MiddleName;
                //employee.Mobile = masterData[i].Mobile;
                //employee.PassportName = masterData[i].PassportName;
                //employee.PassportNo = masterData[i].PassportNo;
                //employee.ResidentId = masterData[i].QatarID;
                //checkModel(employee);
            //}
            return masterErrorsList;
        }

CodePudding user response:

By default it is application/x-www-form-urlencoded content type. I think if you try to send data using json content type , it maybe will work different

add to your ajax

 contentType: 'application/json; charset=utf-8',
dataType: 'json',

and stringify data

data:  JSON.stringify(employees),

you maybe will need to add [FromBody] to the action parameter, but maybe not. Pls let us know.

Update

Starting in ASP.NET Core 2.0.0, both Kestrel and HttpSys began enforcing a 30MB (~28.6 MiB) max request body size limit.

you can change max body size limit. For The following would allow MyAction to accept request bodies up to 200,000,000 bytes [200mb]

 [Route("/Master/SaveMaster")]
 [HttpPost]
[RequestSizeLimit(200_000_000)]
 public List<MasterError> SaveMaster([FromBody]List<MasterData> masterData)

or maybe this (depends on the net core version)

[HttpPost]
[RequestFormLimits(MultipartBodyLengthLimit = 104857600)]

But I don't think that your 50 records take more 1 MB (20kb per record is too much for very base and simple employee object).

CodePudding user response:

Thank you Serge for your constant follow up with me. I really appreciate. The above did not work for me (may be the size of my array was even bigger) but the following worked.

[Route("/Master/SaveMaster")]
[HttpPost]
[RequestFormLimits(ValueCountLimit = int.MaxValue)]
public List<MasterError> SaveMaster([FromForm] List<MasterData> masterData)

That's all what I had to do to make it working perfectly!

  • Related