Передача списка int в запрос HttpGet

у меня есть функция, похожая по структуре на это:

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

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

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

однако, когда я делаю запрос GET для метода:

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

я получаю ошибку при отладке, заявляя, что listOfIds равно null. В нашем контроллере у нас есть несколько общедоступных методов HttpGet, которые работают нормально, и при изменении параметра на один int он работает. Я попытался изменить тип параметра на int[] и IEnumerable<int> тоже, но никаких изменений.

однако при изменении вызова на a HttpPost и передача списка в качестве значения x-www-form-urlencoded, метод работает.

можно ли передать список в метод Get или мне придется использовать Post? Поскольку на самом деле это не метод post (поскольку он возвращает модель значений JSON и ничего не сохраняется на сервере).

4 ответов


Если вы используете MVC WebAPI, то вы можете объявить свой метод следующим образом:

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

и тогда запрос такой: blabla.com/GetTotalItemsInArray?listOfIds=1&listOfIds=2&listOfIds=3

это будет соответствовать массиву [1, 2, 3] в listofids param (и вернуть 3, как ожидалось)


вот быстрый Хак, пока вы не найдете лучшее решение:

  • использовать "?listOfIds=1,2,5,8,21,34"
  • затем:
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 */
    ...

до сих пор у меня есть комбинация комментария @oleksii и ответа от @C. B, но с помощью TryParse для борьбы с ошибками и нулевой проверки, чтобы сделать его необязательным параметром.

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
    }
}

поскольку значения не передаются из формы, мне пришлось изменить ответ @oleksii, связанный сздесь использовать Params вместо Forms и объединил это с предложением от @C. B. проанализировать строковые значения в int.

пока это учитывает традиционное listOfIds=1&listOfIds=2, он по-прежнему требует преобразования строк в ints.


вы также можете передать сериализованный массив в строке запроса на клиенте и десериализовать на стороне сервера:

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

строки запроса:

"MyMethod?listOfIds=" + ArrlistOfIds

, а затем на стороне сервера, просто десериализовать:

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

теперь у вас есть список идентификаторов, которые можно разобрать на int. Int32.TryParse(id, out result)