[HttpGet("{pageNumber}{pageSize?}{filter?}{sortOrder?}", Name = "GetEntriesPaged")]
public ActionResult<List<Entry>> GetEntriesPaged(
int pageNumber, int pageSize = 10, string filter = "", string sortOrder = "desc") {
Run-time exception:
System.ArgumentException: An optional parameter must be at the end of the segment. In the segment '{pageNumber}{pageSize?}{filter?}{sortOrder?}', optional parameter 'pageSize' is followed by 'filter'. Parameter name: routeTemplate
What is the point? I have an optional parameter at the end of the segment, as asked....
PS. The more complete code:
[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;
}
I need for /entries
the GetAll()
method to be used, but with /esntries?pageNumber=3
the GetEntriesPaged(...)
one
No you don't. sortOrder
is at the end, but pageSize
and filter
are not. In short, you cannot have multiple optional parameters like this. It creates too many combinations of routes, which would render it impossible to determine how to route the request or what particular route params to fill. For example, what if you fill in pageSize
and sortOrder
but not filter
? How is ASP.NET Core supposed to know that what you supplied for sortOrder
is not actually meant for filter
?
FWIW, you also need slashes between these route params. Otherwise, there's no way to know where one ends and the next begins. For example, is a route like /111
saying page one with a size of 11, page 11 with a size of 1, or page 111, and no size set? That still doesn't help you with having them all be optional though.
If you need multiple optional things in the URL, it's best to just use the query string to supply them.
UPDATE
You don't need and really shouldn't have multiple actions for paged or not. There's too much common functionality and the difference is too slight. The typical formula is:
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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With