There is an object:

var obj = { prop1: "str", prop2: 5, arr: [{ prop1: "str", prop2: false }] }; 

It must be converted to a GET string of URL parameters for use in ASP.Net Core (for example, passing GET search and filtering parameters to the controller) of the following form:
prop1=str&prop2=5&arr[0].prop1=str&arr[0].prop2=false
, that is, for arrays the index must be specified, and the properties of the objects must be indicated through a dot. The structure of the object is not strictly established, which means the possible presence of nested arrays and objects in different variations. I tried this:

JSON.stringify (obj)

"{"prop1":"str","prop2":5,"arr":[{"prop1":"str","prop2":false}]}"

jQuery.param (obj)

encoded prop1=str&prop2=5&arr%5B0%5D%5Bprop1%5D=str&arr%5B0%5D%5Bprop2%5D=false
decoded prop1=str&prop2=5&arr[0][prop1]=str&arr[0][prop2]=false

As you can see, jQuery.param does almost what it needs, but still it’s not.
How to serialize an object to the required form?

Related Links

  • 2
    Some kind of custom format you want. Are you sure about him? - Stepan Kasyanenko
  • @StepanKasyanenko just the standard format for ASP.Net - XelaNimed
  • one
    Is it better to transfer such data through POST? - Alexander Petrov
  • @AlexanderPetrov is of course much simpler, but in this case it will be impossible to add the search query to the bookmarks and most likely there will be problems with caching, well, it violates the CRUD principle. - XelaNimed 6:51 pm
  • jQuery does the right thing. - Qwertiy

2 answers 2

create the variable obj="str&prop2=5&arr[0].prop1=str&arr[0].prop2=false" and pass

  • The question is how to create it automatically. - andreymal
  • the usual concatenation of strings: obj = str.toString () + "&" + prop2.toStrong () + "= 5 &" ..... and so it started up and went. - Anuar Temirbulat
  • Which immediately makes it impossible to use the & symbol in values. You can’t do that, and it looks awkward - andreymal
  • said the dude who wants to convey in such a sophisticated way). It is possible to change with any sign, for example, the sign -, and on the server side "-" to substitute for &. - Anuar Temirbulat
  • And this is a blatant ignorance, since you are not even aware of standard screening - andreymal

Since I did not find anything sensible, I solved the problem for myself with the following function:

 function getUrlPairs(obj) { var getType = obj => obj === undefined ? 'undefined' : (obj === null ? 'null' : obj.constructor.name), simple = (path, val) => path + '=' + val, simpleEnc = (path, val) => simple(path, encodeURIComponent(val)), typeFunc = { null: simple, undefined: (path, val) => simple(path, ''), Number: simple, Boolean: simple, String: simpleEnc, RegExp: simpleEnc, Date: (path, val) => simpleEnc(path, val.toJSON()), Object: (path, val, dot = '.') => iterate(val, path + dot, name => name), Array: (path, val) => iterate(val, path, name => '[' + name + ']') }, pairs = [], type = getType(obj); function iterate(obj, prefix, wrap) { for (const[name, val] of Object.entries(obj)) { const call = typeFunc[getType(val)]; const tmp = call && call(prefix + wrap(name), val); call && tmp && pairs.push(tmp); } } typeFunc[type] && typeFunc[type]('', obj, ''); return pairs; } 

Below is an example of using and testing the object serialization:

 var obj = { dirty: "&%[]?", nullable: null, undef: undefined, numberProp: 123, now: new Date(), boolProp: true, obj: { objProp1: "objStr", objProp2: false, nullable: null, objInObj: { aa:"aa", bb: true } }, arr: [{ regexProp: new RegExp('^[a-z0-9]+$', 'i'), arrProp12: 321, arrProp13: true, arrProp14: { a: "absdefg", b: true } }, { arrProp21: "rts", arrProp22: 987, arrProp23: false }, ["arrInArr1", "arrInArr2"], [{test:"str"}], null, new Date() ] }; function getUrlPairs(obj) { var getType = obj => obj === undefined ? 'undefined' : (obj === null ? 'null' : obj.constructor.name), simple = (path, val) => path + '=' + val, simpleEnc = (path, val) => simple(path, encodeURIComponent(val)), typeFunc = { null: simple, undefined: (path, val) => simple(path, ''), Number: simple, Boolean: simple, String: simpleEnc, RegExp: simpleEnc, Date: (path, val) => simpleEnc(path, val.toJSON()), Object: (path, val, dot = '.') => iterate(val, path + dot, name => name), Array: (path, val) => iterate(val, path, name => '[' + name + ']') }, pairs = [], type = getType(obj); function iterate(obj, prefix, wrap) { for (const[name, val] of Object.entries(obj)) { const call = typeFunc[getType(val)]; const tmp = call && call(prefix + wrap(name), val); call && tmp && pairs.push(tmp); } } typeFunc[type] && typeFunc[type]('', obj, ''); return pairs; } var res = getUrlPairs(obj); document.getElementById("output").innerHTML = res.join("\n") + "\n\n" + res.join("&"); 
 textarea { width: 90%; } 
 <textarea rows="20" id="output"></textarea> 

  • I don't see any screening anywhere ... - Qwertiy pm
  • one
    @Qwertiy as well ... var encode = str => encodeURIComponent(str); - XelaNimed