40

I have a function similar in structure to this:

[HttpGet]
public HttpResponseMessage GetValuesForList(List<int> listOfIds)
{
    /* create model */        

    foreach(var id in listOfIds)
        model.Add(GetValueForId(id)

    /* create response for model */
    return response;
}

However, when I do a Get request for the method:

{{domain}}/Controller/GetValuesForList?listOfIds=1&listOfIds=2

I get an error when debugging stating that listOfIds is null. In our controller we have a number of public HttpGet methods that work fine, and when changing the parameter to a single int it works. I've tried changing the parameter type to int[] and IEnumerable<int> too, but no change.

However, when changing the call to a HttpPost and passing the list as an x-www-form-urlencoded value, the method works.

Is it possible to pass a list to a Get method, or will I have to use Post? Since it's not actually a post method (as it returns a JSON model of values and nothing is saved to the server).

StormFoo
  • 1,129
  • 2
  • 10
  • 25
  • 1
    Have a look at [this answer](http://stackoverflow.com/a/2776855/706456). The sending bit looks correct, the reading bit needs some tweaking. And [another one](http://stackoverflow.com/a/2301142/706456) where everything appears to be straightforward. – oleksii Jun 10 '13 at 10:50
  • I'd already attempted the second link you supplied with no luck, but the first one lead me to a method that is a combination of that URL and the answer by @C.B., which I have added below. Thanks – StormFoo Jun 10 '13 at 11:18

5 Answers5

56

If you are using MVC WebAPI, then you can declare your method like this:

[HttpGet]
public int GetTotalItemsInArray([FromQuery]int[] listOfIds)
{
       return listOfIds.Length;
}

and then you query like this: blabla.com/GetTotalItemsInArray?listOfIds=1&listOfIds=2&listOfIds=3

this will match array [1, 2, 3] into listOfIds param (and return 3 as expected)

JKennedy
  • 18,150
  • 17
  • 114
  • 198
Liran Brimer
  • 3,418
  • 1
  • 28
  • 23
  • Thank you, I have seen FromUri before, but never thought to try it. Changed accepted answer to this one. – StormFoo May 12 '14 at 15:44
  • link seems to be broken, would be awesome to have the basic client code in the example as well. – Jon Mar 16 '16 at 10:14
  • 2
    @Jon its a fake link (blabla.com).. i just gave an example of how the URL would look in the client. there is no specific code.. you can use it with jQuery, anchor tag, or plain javascript.. – Liran Brimer Mar 16 '16 at 12:54
  • @LiranBrimer Sorry, very stupid of me not to notice that. – Jon Mar 16 '16 at 17:01
  • After adding `[FromUri]`, I can't build my project. It says `The type or namespace name 'FromUri' could not be found` – Kellen Stuart Sep 26 '18 at 23:20
  • 2
    I think `FromUri` needs to change to `FromQuery`. – Chris Peacock Nov 19 '19 at 10:46
4

In addition to @LiranBrimer if you are using .Net Core:

[HttpGet("GetTotalItemsInArray")]
public ActionResult<int[]> GetTotalItemsInArray([FromQuery]int[] listOfIds)
{
       return Ok(listOfIds);
}
Ogglas
  • 62,132
  • 37
  • 328
  • 418
3

Here's a quick hack until you find a better solution:

  • use "?listOfIds=1,2,5,8,21,34"
  • then:
GetValuesForList(string listOfIds)
{
    /* [create model] here */
    //string[] numbers = listOfIds.Split(',');
    foreach(string number in listOfIds.Split(','))
        model.Add(GetValueForId(int.Parse(number))
    /* [create response for model] here */
    ...
C.B.
  • 666
  • 3
  • 18
  • Yeah, I'm hoping to avoid doing any manual list conversion, but if nobody else has a neater answer I'd prefer to do this than make it a POST method. Thanks – StormFoo Jun 10 '13 at 10:42
0

So far I have a combination of the comment by @oleksii and the answer from @C.B, but using TryParse to deal with errors and a null check to make it an optional parameter.

var paramValues = HttpContext.Current.Request.Params.GetValues("listOfIds");
if (paramValues != null)
{
   foreach (var id in paramValues)
   {
        int result; 
        if (Int32.TryParse(id, out result))
            model.Add(GetValueForId(Add(result));
        else
           // error handling
    }
}

Since the values are not passed from a form I had to change the answer @oleksii linked to from here to use Params instead of Forms and combined that with the suggestion from @C.B. to parse the string values to int.

While this allows for the traditional listOfIds=1&listOfIds=2, it still requires converting strings to ints.

Community
  • 1
  • 1
StormFoo
  • 1,129
  • 2
  • 10
  • 25
  • I've set this to my accepted answer, but if anybody has a neater way of doing this please post it and I'll mark yours as the approved answer. – StormFoo Jun 12 '13 at 14:01
  • Please see the answer from @liran-brimer for a better solution. – StormFoo May 12 '14 at 15:45
-2

You can also pass the serialized array in the request string on client and deserialize on server side:

var listOfIds = [1,2,3,45];
var ArrlistOfIds = JSON.stringify(listOfIds);

For the query string:

"MyMethod?listOfIds=" + ArrlistOfIds

And then in the server side, just deserialize:

public ActionResult MyMethod(string listOfIds = null)
{
    List<string> arrStatus = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<string[]>(arrStatusString).ToList();
    .......
}

Now you have a list of ids that could be parsed to int. Int32.TryParse(id, out result)

Mahesh
  • 3,727
  • 1
  • 39
  • 49