3

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:

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

enter image description here

mtholen
  • 1,631
  • 2
  • 15
  • 27
  • If you open up the Chrome console, what's actually being sent with the request? – Camilo Terevinto Dec 27 '17 at 16:53
  • Hi @CamiloTerevinto, Not sure what you are referring to, I mostly use FireFox (or Chrome) but if I check the request with Fiddler i get following header: POST /Processing/updateMatrix HTTP/1.1 Host: localhost:44352 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: en-US,en;q=0.5 Referer: https://localhost:44352/Processing/ProcessEvent/c1cf6457-eb61-434a-98f9-0137d384 __RequestVerificationToken: Content-Type: application/json; charset=utf-8 X-Requested-With: XMLHttpRequest – mtholen Dec 27 '17 at 16:56
  • I've removed some text from header as it is too long to post as comment. – mtholen Dec 27 '17 at 17:05
  • Can you post a screenshot instead? It's much easier to read. Firefox or Chrome, it's the same. I was referring to the actual data being sent – Camilo Terevinto Dec 27 '17 at 17:11
  • 2
    Make sure the properties in your chkBox class are `public`. – Brian Rogers Dec 27 '17 at 17:53
  • @BrianRogers Geesus, can't believe it was THAT stupidly simple, I guess it must have been the 01:30 AM that did it :-) – mtholen Dec 27 '17 at 23:12

1 Answers1

0

@BrianRogers gave the most useful comment, the class has its properties declared as 'just'

String unqReference_01 {get; set;}

That should be obviously be

public String unqReference_01 {get; set;}

Cheers goes out to @BrianRogers for providing the comment.

mtholen
  • 1,631
  • 2
  • 15
  • 27