3

Having the following action:

public IHttpActionResult GetStuff(
    string like = null,
    [FromUri]string[] state = null,
    [FromUri]string[] mode = null,
    [FromUri]string[] label = null,
)

when I query it as /api/stuff?state=A&state=B the model binder instantiates state array with 2 string values and it's kind enough to instantiate empty mode and label arrays so I don't need to check for nulls. However, if I query it as /api/stuff?&state=A&state=B (note extra ampersand) mode and label arrays are no longer empty - they contain a single null elements both. Why?

In my understanding the query strings are equivalent. Is there any way to fix it without writing custom binder?

1 Answer 1

3

The two query strings are not equivalent. Your second query has a second, nameless, parameter.

/api/stuff?state=A&state=B = query-string with 1 parameter, state.

/api/stuff?&state=A&state=B = query-string with 2 parameters, state and a nameless one.

?& translates to a nameless parameter name having a null value.

The Route parser correctly parses state. However it detects a second parameter and it doesn't know where to put it. It ends up putting it in both your other parameters.

The Route parser's logic is similar with this:
- I'm looking for state ... oh here is it, let's populate.
- I'm looking for mode ... nothing found but hey there's a nameless one, let's populate with it.
- I'm looking for label ... nothing found but hey there's a nameless one, let's populate with it.

PS: you can send a nameless query-string parameter like this:

http://www.myurl.com/?=value
Sign up to request clarification or add additional context in comments.

4 Comments

use backticks for code, for word emphasis you can use italics or bold (Ive edited your answer)
Thank you for the tip, I will sure do so from now on.
OMG, this is a weirdest behavior one could expect. In case if, say, there is &extra=1 parameter in the query string the binder still doesn't know where to put 1 (and it doesn't). In other words, if there are no matches there is no reason to put non-matching values anywhere.
In your example if wouldn't put the 1 somewhere else. The situation I have described above happens only with nameless parameters.

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.