As the question title suggests I am trying to post a collection of arrays (an array of arrays if you like) via an $ajax
call to an MVC controller to bind to a class entity in the controller. I have trolled near all the questions I could find on the subject but I can't seem to get it to work, the model simply will not bind.
Although it would be nice to be able to bind to a class entity, I would settle for just being able to process the 'array of arrays', but even that doesn't seem to work. I can't get the array to be read as an 'array' in the controller parameters.
The quest
An HTML page with a variable, but potentially large number of checkboxes (>500) needs to send all values (false values included) with two unique references per checkbox back to the controller for processing. The two unique references are part of the id of the checkbox and get separated before being added to the array.
The problem
when posting from MVC view through $ajax
call, data gets stringified (through JSON.stringify()
) the controller responds and initializes the appropriate number of chkBox
class entities but doesn't fill the class instance properties. (i.e. I get n chkBox
entities all with all properties set to null
Fiddler verifies that values get posted in JSON format and if I write my own I modelbinder the values do show up in the stream, so the values actually get passed to the controller.
Same happens if I pass a single set of three individual values to the controller, however if I pass the set of three values as a single array, the controller responds with a single chkBox
entity, but with all three property-values set to null
.
Javascript function to create JS 'chkBox object'
function chkBox(unqReference_01, unqReference_02, boolean) {
this.unqReference_01 = unqReference_01;
this.unqReference_02= unqReference_02;
this.IsChecked = boolean;
}
Javascript in view
var _chkBoxes = [];
$("input:checkbox[name^='chkCompetitor']").each(function () {
if (_chkBoxes.length < 5) {
var splitID = $(this).attr('id').split("_");
var entry = new chkBox(splitID[1], splitID[2], true);
if (_chkBoxes.indexOf(entry) == -1) {
_chkBoxes.push(entry);
}
}
});
//Submit _chkBoxes
var updateMatrix = $.ajax({
type: "POST",
dataType: 'json',
contentType: 'application/json; charset=utf-8',
//traditional: true,
url: '/Processing/updateMatrix',
data: JSON.stringify(_chkBoxes)
});
The original Class: (the one that produced the incorrect behaviour)
[SerializableAttribute]
public class chkBox
{
String unqReference_01 { get; set; }
String unqReference_02 { get; set; }
String IsChecked { get; set; }
public chkBox()
{
}
}
EDIT: the solution (too simple really)
Set all the class properties to public...
The edited Class:
[SerializableAttribute]
public class chkBox
{
public String unqReference_01 { get; set; }
public String unqReference_02 { get; set; }
public String IsChecked { get; set; }
public chkBox()
{
}
}
The Controller:
[HttpPost]
public JsonResult UpdateMatrix(General.chkBox[] chkBoxes)
//public JsonResult UpdateMatrix(IEnumerable<General.chkBox> chkBoxes)
//public JsonResult UpdateMatrix(string IsChecked, String unqReference_01, String unqReference_01)
{
return null;
}
Using:
- ASP.NET MVC 5.2.3
- EF 6.2.0
- jQuery 3.2.1
Read & Tried:
- MVC3 & JSON.stringify() ModelBinding returns null model
- ASP.NET MVC3 JSON Model-binding with nested class
- ModelBindingContext.ValueProvider.GetValue(bindingContext.ModelName) returns null
- ASP.NET MVC3 JSON Model-binding with nested class
- ModelBinding not deserializing json
- Post JSON array to mvc controller
- https://haacked.com/archive/2011/06/30/whatrsquos-the-difference-between-a-value-provider-and-model-binder.aspx/
Header screenshot
Please note that the header uses the actual names of the class & properties, the properties match both ends (i.e. in JSON and in class) uBoatKey = unqReference_01 uDivisionRaceKey = unqReference_02