web-dev-qa-db-fra.com

Paramètre facultatif dans le modèle de route d'API Web .NET Core

[HttpGet("{pageNumber}{pageSize?}{filter?}{sortOrder?}", Name = "GetEntriesPaged")]
public ActionResult<List<Entry>> GetEntriesPaged(
    int pageNumber, int pageSize = 10, string filter = "", string sortOrder = "desc") {

Exception d'exécution:

System.ArgumentException: un paramètre facultatif doit se trouver à la fin du segment. Dans le segment '{pageNumber} {pageSize?} {Filter?} {SortOrder?}', Le paramètre facultatif 'pageSize' est suivi de 'filter'. Nom du paramètre: routeTemplate

Dans quel but? J'ai un paramètre facultatif à la fin du segment, comme demandé ....

PS. Le code le plus complet:

[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;
}

J'ai besoin de /entries La méthode GetAll() à utiliser, mais avec /esntries?pageNumber=3 La GetEntriesPaged(...) one

5
Serge

Non, non. sortOrder est à la fin, mais pageSize et filter ne le sont pas. En bref, vous ne pouvez pas avoir plusieurs paramètres facultatifs comme celui-ci. Il crée trop de combinaisons de routes, ce qui rendrait impossible de déterminer comment acheminer la demande ou quels paramètres de route particuliers à remplir. Par exemple, que faire si vous remplissez pageSize et sortOrder mais pas filter? Comment ASP.NET Core est-il censé savoir que ce que vous avez fourni pour sortOrder n'est pas réellement destiné à filter?

FWIW, vous avez également besoin de barres obliques entre ces paramètres de route. Sinon, il n'y a aucun moyen de savoir où l'un se termine et le suivant commence. Par exemple, est un itinéraire comme /111 dire la première page avec une taille de 11, la page 11 avec une taille de 1 ou la page 111, et aucune taille définie? Cela ne vous aide toujours pas à les faire tous facultatifs.

Si vous avez besoin de plusieurs éléments facultatifs dans l'URL, il est préférable d'utiliser simplement la chaîne de requête pour les fournir.

MISE À JOUR

Vous n'avez pas besoin et ne devriez vraiment pas avoir plusieurs actions paginées ou non. Il y a trop de fonctionnalités communes et la différence est trop faible. La formule typique est:

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());
}
5
Chris Pratt