66

I want to do this, but I want to also be able to pass in arrays into the query string. I've tried things like:

http://www.sitename.com/route?arr[]=this&arr[]=that
http://www.sitename.com/route?arr[]=this&that
http://www.sitename.com/route?arr[0]=this&arr[1]=that
http://www.sitename.com/route?arr0=this&arr1=that
http://www.sitename.com/route?arr=this&arr=that

And my route in the C# code looks like this:

[Route("route")]
[HttpGet]
public void DoSomething(string[] values)
{
    // ...
}

But in all of these cases, values is always null when it gets to the C# code. What do I need my query string to be to pass an array of strings?

3
  • 1
    don't think this is possible Commented Apr 13, 2017 at 17:05
  • 4
    Your parameter name doesn't match. Change arr or values. Commented Feb 11, 2018 at 3:31
  • Does this answer your question? Pass an array of integers to ASP.NET Web API? Commented Oct 25, 2020 at 20:18

8 Answers 8

63

Use a parameter name in the query string. If you have an action:

public void DoSomething(string[] values)

Then use values in the query string to pass an array to a server:

?values=this&values=that
Sign up to request clarification or add additional context in comments.

8 Comments

That's in the list of things I tried. It didn't work for me.
@user3685285, I checked it and it works as described. Could you pass a single value to the action like Foo(string value) ?
This is how I knew how to do it, but it did not work for me either. Unexpected end of Stream, the content may have already been read by another component
Are you missing the [FromUri] attribute?
@MateuszMigała yes, it worked on 1.1 but there is a bug on Core 2.1 as described in the answer stackoverflow.com/a/52222184/5112433. The bug was fixed in 2.2.
|
47

Delimited string is not the standard. Think also about the client if you support swagger or other generators.

For those who wonder about .net core 2.1 bug which receives an empty list, the work around is here: https://github.com/aspnet/Mvc/issues/7712#issuecomment-397003420

It needs a name parameter on FromQuery

[FromQuery(Name = "employeeNumbers")] List<string> employeeNumbers

5 Comments

Is this a bad practise to use a named parameter to use complex types with [FromQuery] attribute?
Array and list behave similarly in this context. But even though this answer is out of the context of current question, I would say, no it's not a bad practice. you can even have complex types like Person and feed it's properties via FromQuery: Look at this for more info: learn.microsoft.com/en-us/aspnet/web-api/overview/…
I don't have any idea why, but this worked like a charm, thank you so much! Before naming my parameter like your answers says I was getting a 415 HTTP error, now everything is 200.
This answer is solving the wrong problem/ is out of date. You don't need the name param if you match the param name to the values passed in, as other answers point out.
My querystring was in ?arr[]=this&arr[]=that format, and the only way I could get it to work was by including the square brackets in the FromQuery name: [FromQuery(Name = "employeeNumbers[]")] List<string> employeeNumbers. I've no idea whether that is valid or not.
45

I have found a solution. For example, if you have a query like this:

http://www.sitename.com/route?arr[]=this&arr[]=that

You must define in parameter as [FromQuery(Name = "arr[]")]. The name of parameter must include square brackets. As result we can see:

public void DoSomething([FromQuery(Name = "arr[]")] string[] arr)

2 Comments

You can remove [] from both query and parameter declaration, e.g. route?arr=this&arr=that should work
This is very helpful for using JQuery's $.get(), which will add the "[]" to the end of the array name.
11

I had to do something similar to this, but instead of strings, i used a list of long to pass some id for a search. Using a multiple select option, the chosen values are sent to the method (via get) like this:

[HttpGet("[action]")]
public IActionResult Search(List<long> idsSelected)
{
    ///do stuff here
}

I also use Route("[controller]") before the class declaration. Works just fine, but the list of items is broken into multiple parameters in the url, as shown below.

http://localhost:5000/Search/idsSelected=1&idsSelected=2

Comments

7

Given:

public ValuesController
{
    public IACtionResult Get([FromUri]string[] arr)
    {
        Return Ok(arr.Length);
    }
}

The following request will work:

GET /api/values/?arr[0]=a&arr[1]=b&arr[2]=c

Comments

7

In the end, I just passed in a single delimited string, then used string.Split to separate on the server side. Not the prettiest solution, but it works. Until someone comes up with a better answer, this is all I got. I should reiterate that I'm using .NET Core, and these query strings are framework specific.

Update: An (arguable) benefit of this approach is that you pass the values together (e.g. arr=value1,value2) instead of repeating the key (arr=value1&arr=value2).

6 Comments

In your example, you had arr=1&arr=2 but your variable name is values, so it should surely be values=1&values=2 The name must match.
Think about the tools that generate client for your api. I would prefer to see an array of ids as parameter to the client instead of an string parameter which is not self describing.
@MohsenTabareh That's what I was asking. But no one could come up with a way that worked for me. So I just had to do the cheap hack. See the comments in Ilya's answer. Read the context before downvoting please...
And have you tried the solutions that I & @abatishchev provided?
Well I'm not even working at that company anymore. I asked this question more than a year ago. Not sure if there was any updates to .NET Core that addressed this.
|
6

I found two problems in your question:

  1. Your query has parameters named arr while you Contrller's Action has values.
  2. I don't know why, but you gotta name your parameter (as answered here) so the Asp .NET ModelBinder can work as expected. Like this:
public void DoSomething([FromQuery(Name = "values")] string[] values)

After doing that, everything should work as expected.

1 Comment

Thanks, it's fixed now.
4

I had the same problem with .NET Core 3, while trying to pass in a string Array. I solved it by passing in the query parameter as a temporary json string. I then deserialized the string to the resulting array using Newtonsoft's Json package

using Newtonsoft.Json;

public IActionResult Get([FromQuery(Name = "array")] string arrayJson)
{
    List<string> array = JsonConvert.DeserializeObject<List<string>>(arrayJson);
}

3 Comments

The solution is very similar to the accepted answer stackoverflow.com/a/43474678/52277 and user3685285’s Split is more simple than JsonConvert.DeserializeObject<List<string>>
It's annoying to have to do this but in the end, I couldn't find an easier solution when using deep objects.
[FromQuery(Name = "array")] attribute is a better approach than split as it is strongly typed. When using split, you have to write code to type check and then convert.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.