I have the following jQuery extension to serialize form as Json object
(function () {
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name]) {
if ((typeof (this.value) === "boolean") ||
(typeof (this.value) === "string" && this.value != undefined && (this.value.toLowerCase() === "true" || this.value.toLowerCase() === "false"))) {
o[this.name] = ((o[this.name] == "true") | (this.value == "true")) ? true : false; //Sets value to true if one of two bits is true
}
else {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
}
} else {
o[this.name] = this.value || '';
}
});
return o;
};
})(jQuery)
Then i have Html form
<form id="myform">
<input name"AccountNumbers[0]" value="1111" />
<input name"AccountNumbers[1]" value="2222" />
// some other properties
</form>
Then using Ajax i am posting the form to server
var obj = $("#myform").serializeObject();
$.ajax({
type: "POST",
data: JSON.stringify(obj),
url: "/save",
contentType: "application/json; charset=utf-8",
processData: true,
cache: false
})
The serializeObject method create json object as
{
"AccountNumbers[0]: "1111",
"AccountNumbers[1]: "2222"
....
....
}
I am using ASP.NET Core. So on server i have Controller action method
public class MyModel
{
public string[] AccountNumbers {get;set;}
// some other properties
}
[HttpPost]
public async Task<IActionResult> Save([FromBody]MyModel model)
{
// do something
}
ISSUE: On server, model's all the properties are populated except AccountNumbers. Somehow the model binding is not able to bind the string array.
UPDATE 1
as pointed out in the comments below issue was the array structure. I have changed my jQuery extension however it works for one level. But if i have hierarchy then it will not work
(function () {
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
var name = this.name;
var val = this.value;
if (name && name.indexOf("[") > -1) {
name = name.substr(0, name.lastIndexOf("["));
}
if (o[name]) {
if ((typeof (val) === "boolean") ||
(typeof (val) === "string" && val != undefined && (val.toLowerCase() === "true" || val.toLowerCase() === "false"))) {
o[name] = ((o[name] == "true") | (val == "true")) ? true : false; //Sets value to true if one of two bits is true
}
else {
if (!o[name].push) {
o[name] = [o[name]];
}
o[name].push(val || '');
}
} else {
o[name] = val || '';
}
});
return o;
};
})(jQuery)
The extension will not work for
<input name="Person[0].AccountNumber[0]" value="1111" />
<input name="Person[0].AccountNumber[1]" value="2222" />
<input name="Person[1].AccountNumber[0]" value="3333" />
<input name="Person[1].AccountNumber[1]" value="4444" />