2

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" />
2
  • With a hierarchy, you could adapt your solution to recursively parse the parts. However, at this stage, it might make sense to consider a data binding engine for more complex structures. Something like Vue could fit your needs as it doesn't require much to drop into a page. Commented May 15, 2020 at 20:45
  • using Vue is like completely changing architecture. I need this to work on one page Commented May 15, 2020 at 21:17

1 Answer 1

1

You will need to update your AccountNumbers property on your JSON body to be an array type. ASP.NET Core is seeing each of the indexed AccountNumbers properties as different properties and not part of a collection.

Something like this should work:

{
  AccountNumbers: ["1111", "2222"]
}

If this were a GET request, you could pass each item of the array as query string parameters with the same name. For example:

/save?AccountNumbers=1111&AccountNumbers=2222

Note: This approach will not work with JSON POST bodies as duplicate keys aren't allowed in valid JSON.

Sign up to request clarification or add additional context in comments.

1 Comment

you are correct i need to change my jQuery extension to create correct array structure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.