如何使用FromQuery传递复杂的C#对象

时间:2019-04-04 16:06:24

标签: c# angularjs asp.net-mvc asp.net-core

在我的客户端代码中,我有一个像这样的对象:

{
  "selectedItems": [
    4016,
    3937
  ],
  "selectedStatuses": [],
  "search": "foo"
}

我想映射到C#DTO上

public class FilterModel
{
    public List<int> SelectedItems { get; set; }
    public List<int> SelectedStatuses { get; set; }
    public string Search { get; set; }
}

但是它在GET查询中使用,因此我无法仅通过FromBody通过FromQuery传递。控制器操作中已经有一些基本参数:

[HttpGet("{id}/filter/{typeId}")]
public async Task<IActionResult> GetFilteredData([FromRoute]int id, 
    [FromRoute]int typeId,
    [FromQuery]FilterModel filters = null)

客户端,我在Angular中使用$ http构建此查询。如何设置$ http调用以将过滤器对象创建为查询字符串?

2 个答案:

答案 0 :(得分:2)

简单来说,您的查询名称必须与要发布的输入名称相同,例如filters.SelectedItems[](对于列表中的每个项目重复),filters.SelectedStatuses[](对于每个项目重复) (在列表中)和filters.Search。例如:

?filters.SelectedItems[]=item1&filters.SelectedItems[]=item2&filters.SelectedItems[]=item3&filters.SelectedStatuses[]=status1&filters.SelectedStatuses[]=status2&filters.SelectedStatuses[]=status3&filters.Search=keyword

注意:这里有一定的回旋余地,但是最终,您将达到最大请求长度限制。在大多数情况下,您应该不会有任何问题,但是,如果您开始选择100多种东西,则可能需要其他计划。

FWIW,您始终可以只使用帖子,尤其是通过AJAX进行发布时,因为无论哪种方式对用户都是无缝的。

答案 1 :(得分:1)

如果使用的是Ajax,一种简单的方法是添加traditional:true以使用传统的参数序列化样式。请参阅here

var data =
        {
            "selectedItems": [
                4016,
                3937
            ],
            "selectedStatuses": [12, 34],
            "search": "foo"
        };
        $.ajax({
            url: "your url", //directly like /Home/{id}/filter/{typeId}              
            type: 'GET',
            data: data,
            traditional: true,
            success: function (result) {

            }
        });