How to send a list of integers to web api 2 get request?

Liran Friedman picture Liran Friedman · Jul 6, 2016 · Viewed 14.8k times · Source

I am trying to accomplish this task in which I need to send a list of id's (integers) to a web api 2 get request.

So I've found some samples here and it even has a sample project, but it doesn't work...

Here is my web api method code:

[HttpGet]
[Route("api/NewHotelData/{ids}")]
public HttpResponseMessage Get([FromUri] List<int> ids)
{
    // ids.Count is 0
    // ids is empty...
}

and here is the URL which I test in fiddler:

http://192.168.9.43/api/NewHotelData/?ids=1,2,3,4

But the list is always empty and none of the id's are passing through to the method.

can't seem to understand if the problem is in the method, in the URL or in both...

So how this is possible to accomplish ?

Answer

Aleksey L. picture Aleksey L. · Jul 6, 2016

You'll need custom model binder to get this working. Here's simplified version you can start work with:

public class CsvIntModelBinder : IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var key = bindingContext.ModelName;
        var valueProviderResult = bindingContext.ValueProvider.GetValue(key);
        if (valueProviderResult == null)
        {
            return false;
        }

        var attemptedValue = valueProviderResult.AttemptedValue;
        if (attemptedValue != null)
        {
            var list = attemptedValue.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries).
                       Select(v => int.Parse(v.Trim())).ToList();

            bindingContext.Model = list;
        }
        else
        {
            bindingContext.Model = new List<int>();
        }
        return true;
    }
}

And use it this way (remove {ids} from route):

[HttpGet]
[Route("api/NewHotelData")]
public HttpResponseMessage Get([ModelBinder(typeof(CsvIntModelBinder))] List<int> ids)

If you want to keep {ids} in route, you should change client request to:

api/NewHotelData/1,2,3,4

Another option (without custom model binder) is changing get request to:

?ids=1&ids=2&ids=3