6

I have a controller action like:

Public ActionResult MyAction(int[] stuff){}

I make a JSON request like:

$.getJSON(url, { stuff: [] })

When it gets to C# it looks like an array with one element in it, which is zero (i.e. like if I did int[] stuff = {0};).

Is this new with MVC 2 or .NET 4? It seems to have changed recently, but I haven't found a smoking gun. How can I get around this? This can't possibly be expected behavior, can it?

2
  • 1
    You'll notice also that this behavior has nothing to do with AJAX/JSON. You'll get the same result if you call your controller and pass "stuff" via the querystring (e.g. /MyAction?stuff= ) Commented Oct 27, 2010 at 19:10
  • Very nicely broken down in the accepted answer here: stackoverflow.com/questions/23108272/… Commented Jun 30, 2020 at 13:40

2 Answers 2

3

I think this is a bug in MVC:

// create a vpr with raw value and attempted value of empty string
ValueProviderResult r = new ValueProviderResult("", "", System.Globalization.CultureInfo.CurrentCulture);
// this next line returns {0}
r.ConvertTo(typeof(int[]));

If we look at ValueProviderResult.cs in function UnwrapPossibleArrayType, we see:

// case 2: destination type is array but source is single element, so wrap element in array + convert
object element = ConvertSimpleType(culture, value, destinationElementType);
IList converted = Array.CreateInstance(destinationElementType, 1);
converted[0] = element;
return converted;

It forces converted[0] to be element, and ConvertSimpleType casts "" to 0. So I'm closing this question, unless someone has more info.

EDIT: Also, this is not in revision 17270, so if you're making a list of things which change from MVC 1 to MVC 2, this is one of them.

Sign up to request clarification or add additional context in comments.

Comments

0

When I tested the code I got null array in the controller action and not an array with one element.

In jquery 1.4 and later the way parameters are serialized during an AJAX request have changed and is no longer compatible with the default model binder. You could set the traditional parameter when performing the request:

$.getJSON(url, $.param({ stuff: [ 1, 2, 3 ] }, true));

or

$.ajax({
    url: url,
    type: 'GET',
    dataType: 'JSON',
    data: { stuff: [ 1, 2, 3 ] },
    traditional: true,
    success: function(res) { }
});

1 Comment

I'm using traditional, and I still get this. See Hector's comment; the problem still occurs when you just put in the url ?var=

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.