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.
In the controller, I will receive the passed employee array as shown below.
But if I pass a big JavaScript array object, its value is null.
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!