.NET Core Web API路由模板中的可选参数

问题描述 投票:3回答:1
[HttpGet("{pageNumber}{pageSize?}{filter?}{sortOrder?}", Name = "GetEntriesPaged")]
public ActionResult<List<Entry>> GetEntriesPaged(
    int pageNumber, int pageSize = 10, string filter = "", string sortOrder = "desc") {

运行时异常:

System.ArgumentException:可选参数必须位于段的末尾。在细分'{pageNumber} {pageSize?} {filter?} {sortOrder?}'中,可选参数'pageSize'后跟'filter'。参数名称:routeTemplate

有什么意义?我在段的末尾有一个可选参数,如所要求的....

PS。代码越完整:

[HttpGet]
public ActionResult<List<Entry>> GetAll() {
    var result = _db.Entries.OrderByDescending(x => x.Date).ToList();
    return result;
}

[HttpGet("{pageNumber}{pageSize?}{filter?}{sortOrder?}", Name = "GetEntriesPaged")]
public ActionResult<List<Entry>> GetEntriesPaged(int pageNumber = 1, int pageSize = 10, string filter = "", string sortOrder = "desc") {
    int take = pageSize;
    int skip = ((pageNumber - 1) * pageSize);
    IQueryable<Entry> result;

    if (sortOrder == "asc") {
        result = _db.Entries.OrderBy(x => x.Date);
    }
    else {
        result = _db.Entries.OrderByDescending(x => x.Date);
    }

    return result.Skip(skip).Take(take).Where(x => x.Origin.Contains(filter)).ToList();
}

[HttpGet("{id}", Name = "GetEntry")]
public ActionResult<Entry> GetById(long id) {
    var item = _db.Entries.Find(id);
    if (item == null) {
        return NotFound();
    }
    return item;
}

我需要/entries使用GetAll()方法,但与/esntries?pageNumber=3 GetEntriesPaged(...)

asp.net-core asp.net-core-webapi asp.net-core-webapi-2.1
1个回答
5
投票

不,你没有。 sortOrder在最后,但pageSizefilter不是。简而言之,您不能有这样的多个可选参数。它创建了太多的路由组合,这使得无法确定如何路由请求或填写什么特定路由参数。例如,如果你填写pageSizesortOrder而不是filter怎么办? ASP.NET Core如何知道你为sortOrder提供的内容实际上并不适用于filter

FWIW,你还需要在这些路线参数之间斜线。否则,无法知道结束的地方和下一个结束的地方。例如,像/111这样的路线是说大小为11的第1页,大小为1的第11页,还是第111页,没有设置大小?尽管如此,这仍然没有帮助你让他们都是可选的。

如果URL中需要多个可选项,最好只使用查询字符串来提供它们。

UPDATE

您不需要并且实际上不应该为分页或不执行多个操作。有太多常见功能,差别太小。典型的公式是:

public async Task<IActionResult> GetAll(int? page = null, int pageSize = 10)
{
    var query = _context.Foos;
    if (page.HasValue)
    {
        query = query.Skip((page.Value - 1) * pageSize).Take(pageSize);
    }

    return Ok(await query.ToListAsync());
}
© www.soinside.com 2019 - 2024. All rights reserved.