【问题标题】:Passing a list of int to a HttpGet request将 int 列表传递给 HttpGet 请求
【发布时间】:2013-06-05 23:24:50
【问题描述】:

我有一个类似结构的函数:

[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 为空。在我们的控制器中,我们有许多可以正常工作的公共 HttpGet 方法,并且当将参数更改为单个 int 时,它可以正常工作。我也尝试将参数类型更改为int[]IEnumerable&lt;int&gt;,但没有任何变化。

但是,当将调用更改为 HttpPost 并将列表作为 x-www-form-urlencoded 值传递时,该方法有效。

是否可以将列表传递给 Get 方法,还是必须使用 Post?因为它实际上不是一个 post 方法(因为它返回值的 JSON 模型并且没有任何内容保存到服务器)。

【问题讨论】:

  • 看看this answer。发送位看起来正确,读取位需要一些调整。还有another one,一切看起来都很简单。
  • 我已经尝试过您提供的第二个链接,但没有成功,但第一个链接将我引向一个结合了该 URL 和@CB 答案的方法,我在下面添加了该链接.谢谢

标签: c# web-services rest get http-get


【解决方案1】:

如果您使用的是 MVC WebAPI,那么您可以像这样声明您的方法:

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

然后你像这样查询: blabla.com/GetTotalItemsInArray?listOfIds=1&amp;listOfIds=2&amp;listOfIds=3

这会将数组 [1, 2, 3] 匹配到 listOfIds 参数中(并按预期返回 3)

【讨论】:

  • 谢谢,我以前看过FromUri,但没想过要试试。将接受的答案更改为这个。
  • 链接似乎已损坏,如果在示例中也有基本的客户端代码,那就太棒了。
  • @Jon 它是一个假链接 (blabla.com).. 我只是举例说明了 URL 在客户端中的外观。没有具体的代码..你可以用jQuery、锚标签或纯javascript..
  • @LiranBrimer 对不起,我很愚蠢,没有注意到这一点。
  • 我觉得FromUri需要改成FromQuery
【解决方案2】:

在您找到更好的解决方案之前,这里有一个快速技巧:

  • 使用“?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 */
    ...

【讨论】:

  • 是的,我希望避免进行任何手动列表转换,但如果没有其他人有更好的答案,我宁愿这样做,也不愿将其设为 POST 方法。谢谢
【解决方案3】:

如果您使用.Net Core,除了@LiranBrimer:

[HttpGet("GetTotalItemsInArray")]
public ActionResult<int[]> GetTotalItemsInArray([FromQuery]int[] listOfIds)
{
       return Ok(listOfIds);
}

【讨论】:

    【解决方案4】:

    到目前为止,我结合了@oleksii 的评论和@C.B 的答案,但使用 TryParse 处理错误并使用 null 检查使其成为可选参数。

    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 从here 更改为使用Params 而不是Forms,并将其与@C.B. 的建议相结合。将字符串值解析为 int。

    虽然这允许使用传统的 listOfIds=1&amp;listOfIds=2,但它仍然需要将字符串转换为整数。

    【讨论】:

    • 我已将此设置为我接受的答案,但如果有人有更简洁的方法,请发布它,我会将你的答案标记为已批准的答案。
    • 请参阅@liran-brimer 的答案以获得更好的解决方案。
    【解决方案5】:

    您也可以在客户端的请求字符串中传递序列化的数组,并在服务器端进行反序列化:

    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 的 id 列表。 Int32.TryParse(id, out result)

    【讨论】:

      猜你喜欢
      • 2017-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-16
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      相关资源
      最近更新 更多