7

I have a jQuery ajax call in which I am trying to send the int IDs of users which can be selected from a table of checkboxes.

I am having a problem with the case that no users are selected. I would expect an empty array but in fact I receive an array of length = 1, containing userId 0 (i.e. an unassigned int value).

The following snippet reproduces the problem

$('#test').click(function () {
    var numbers = $('.noElements').map(function () {
        // (selector does not match any elements, to demonstrate)
        return 1;
    }).get();

    $.ajax({
        url: '/MyController/Test',
        type: "GET",
        data: { numbers: numbers, count: numbers.length }
    });
});


public ActionResult Test(IEnumerable<int> numbers, int count)
{
    Assert(numbers.Count() == count);
    return null;
}

The Assert fails because numbers is List<int> { 0 }. Why is the binding happening like this?

fearofawhackplanet
  • 52,166
  • 53
  • 160
  • 253
  • The code is little confusing, you are setting numbers to "1" i.e. numbers.Count() is 1. But ideally when no users are selected, the numbers.Count() should be ideally "0". And its then the assert is failing. Is this correct ? – Pawan Mishra Nov 08 '11 at 13:22
  • Can you try the following change in your action method and see if that works or not. Replace IEnumerable with IList. See if it works, if yes, then I will add a detailed answer to this post. – Pawan Mishra Nov 08 '11 at 13:29
  • Numbers is a 0 length array of 1s. Changing from `IEnumerable` to `IList` will not make any difference. – fearofawhackplanet Nov 08 '11 at 13:41

1 Answers1

1

I believe that the default model binder will convert the empty string that is passed to it by the jQuery AJAX call into a integer array that contains a single element containing the default value of an integer (0). Your code would work if you did something like this-

$('#test').click(function () {
    var numbers = $('.noElements').map(function () {
        return 1;
    });
    if (numbers.length == 0) {
        numbers = null;
        count = 0;
    }
    else count = numbers.length;

    $.ajax({
        url: '/Home/Test',
        type: "GET",
        data: { numbers: numbers, count: count }
    });
});

See this question for further info and alternate solutions - How to post an empty array (of ints) (jQuery -> MVC 3)

Community
  • 1
  • 1
ipr101
  • 24,096
  • 8
  • 59
  • 61
  • Yeah it looks like there is no support in MVC for passing an empty array. How strange. I wonder what their reasoning was for implementing it this way, it's not immediately apparent to me anyway. – fearofawhackplanet Nov 08 '11 at 14:01
  • Actually, I had to delete my answer, cause in my case even non-empty arrays got serialized in improper way (mvc2) – Bartosz Nov 08 '11 at 14:03