Необязательный параметр в шаблоне маршрута.NET Core Web API

[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(...) один

1 ответ

Решение

Нет, ты не sortOrder в конце, но pageSize а также filter не. Короче говоря, вы не можете иметь несколько дополнительных параметров, подобных этому. Он создает слишком много комбинаций маршрутов, из-за которых невозможно определить, как направить запрос или какие конкретные параметры маршрута заполнить. Например, что если вы заполните pageSize а также sortOrder но нет filter? Как ASP.NET Core должен знать, что вы поставили для sortOrder на самом деле не предназначен для filter?

FWIW, вам также нужны косые черты между этими параметрами маршрута. В противном случае невозможно узнать, где заканчивается один и начинается следующий. Например, это маршрут как /111 говорят одну страницу размером 11, страницу 11 размером 1 или страницу 111, а размер не установлен? Это все еще не поможет вам иметь их все необязательно.

Если вам нужно несколько дополнительных вещей в URL, лучше всего использовать строку запроса для их предоставления.

ОБНОВИТЬ

Вам не нужно и на самом деле не должно быть несколько действий для страниц или нет. Там слишком много общей функциональности, а разница слишком мала. Типичная формула:

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());
}
Другие вопросы по тегам