将复杂类型的集合与查询字符串中的其他属性绑定

时间:2018-11-09 14:25:47

标签: c# asp.net-core

我正在使用asp.net core v2.1,我有一个从Controller继承来的控制器,该控制器包含一个动作,该动作具有基于以下模型的用FromQuery装饰的参数:

public class PagingControl<T>
{
    public ColumnSort[] ColumnSorts { get; set; }

    public T ColumnFilters { get; set; }

    public int Page { get; set; }

    public int PerPage { get; set; }
}

public class ColumnSort
{
    public string Field { get; set; }

    public SortType Type { get; set; }
}

public enum SortType
{
    Asc = 0,
    Desc
}

generic参数表示具有可空属性的纯poco,可提供定义良好的列和值进行过滤。 PagingControl<T>模型描述了通过操作实现分页所需的所有参数。

ColumnSorts属性是一个集合,因为可以进行多个连续的列排序。

我已经读过Array or List in query string does not get parsed,但如果我理解这一点,就无法拥有一个能够接受所有查询参数的模型。

为了成功实现分页的全部功能,需要所有参数。如果ColumnSorts不是集合,这与单列排序保持一致,则效果很好。

有人知道这种情况下使用查询字符串的解决方法吗?

1 个答案:

答案 0 :(得分:0)

您上述的问题已得到解决。另外,即使它不是固定的,也可以绕过[FromQuery(Name="xxx")]。参见dougbu's walkaround

似乎您使用的是[ApiController],我用2.1.3022.1.402进行了测试,它工作正常。

假设您要针对MyColoumnFilter进行查询,该查询将用作T ColumnFilters类中的PagingControl<T>

public class MyColumnFilter
{
    public string FieldA { get; set; }
    public string FieldB { get; set; }
}

,您在服务器端的操作方法是:

[Route("api/[controller]")]
[ApiController]
public class MyController : Controller
{
    // GET api/values
    [HttpGet]
    public IActionResult Get([FromQuery]PagingControl<MyColumnFilter> pc)
    { 
        return new JsonResult(pc);
    } 

    // ...
}

如果您发送如下请求:

GET https://localhost:5001/api/my?page=1&perPage=10&columnFilters.fieldA=1&columnFilters.fieldB=2&columnSorts[0].Field=cs1&columnSorts[0].Type=Asc&columnSorts[1].Field=cs2&columnSorts[1].Type=Desc HTTP/1.1

它将按预期工作:

enter image description here

查询字符串可分为4部分:

  1. page:1的int
  2. perPage:int为10
  3. columnFilters:columnFilters.fieldA=1&columnFilters.fieldB=2
  4. columnSorts []:由于ColumnSorts是一个数组,因此我们应该像 columnSorts[0].Field=xx&columnSorts[0].Type=Asc&columnSorts[1].Field=...
  5. 那样构造参数

请注意,如果使用GET http方法,它将使查询字符串变得相当复杂。请参阅我的另一个答案下的Chris Pratt's comment