It has been quite awhile since I've dealt with complex model binding across a set of inputs in mvc.
If one controller action's params (or a property on one of those params) is an IEnumerable<T>
then Mvc will not write the element names in a way that will properly go back to the server.
I Json serialized the parent model into an html attribute on to some parent of the value(s) I want to submit. Some questions allow many answers, and I want to save each time a question answer is changed.
I'm working on making that serialization not contain the about to be consumedIEnumerable<T>
property.
var save = function (element, value, event, previousValue,debug) { console.log('saving:' + value + ' to ' + saveUrl); var demoText = $(element).closest('[data-demographic]').attr('data-demographic'); var demoJson = htmlDecode(demoText); var demoModel = JSON.parse(demoJson); var oldAnswers = demoModel.PossibleAnswers; demoModel.PossibleAnswers = []; //TODO: handle multi-select, single-select radio, etc... if (Object.prototype.toString.call(value) === '[object Array]') { //value and previousValue could be arrays for multi-select answers $.each(value, function (i, e) { demoModel.PossibleAnswers.push({ Id: e }); }); } else { demoModel.PossibleAnswers.push({ Id: value,Text:$(element).parent().text().trim() }); } var data = JSON.stringify(demoModel); data=data.replace('][', '].['); $.ajax({ dataType: 'json', url: saveUrl, contentType: 'application/json; charset=utf-8', accept: debug ? { json: 'application/json', } : {}, type: 'POST', data: data, success: function (data, status, jqXhr) { if (debug) { var answerMirror = data.PossibleAnswers; delete data.PossibleAnswers; console.log(data); console.log(answerMirror); } else { //update dom to new read-only model? //TODO: adjust with new html console.log(data); } } }); };There's the heart of it. Notice I don't actually have to use the special
name=foo.bar[0].Id
on my inputs, but that is probably still a good idea.
This thing was almost working without doing any JSON.stringify
but the IEnumerable<T>
data was ignored by Mvc's model binder. With that in mind, I had to specify the contentType
of the ajax request.