Реализация разбиения на страницы в ASP.NET Core 2.1 Web API

Я искал, но не нашел статей о том, как реализовать логику разбиения на страницы в приложении ASP.NET WebAPI Core 2.1...

У меня есть следующее

[Route("api/[controller]")]
[ApiController]
[EnableCors("AllowMyOrigin")]
public class EntriesController : ControllerBase
{
    private readonly EntriesContext _context;

    public EntriesController(EntriesContext context) {
        _context = context;

        if (_context.Entries.Count() == 0) {
            _context.Entries.Add(new Entry { From = "default", To = "default" });
            _context.SaveChanges();
        }
    }

    [HttpGet]
    public ActionResult<List<Entry>> GetAll() {
        return _context.Entries.ToList();
    }

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

Теперь я хочу, чтобы мои записи были разбиты на страницы с использованием новых параметров page а также pageSize, Сказать

/api/entries?pageSize=3&page=2 

Должен ли я использовать GetAll() метод, добавив несколько HTTP-параметров к нему, или, скорее, создать новый метод? Нет особого смысла использовать page без pageSize как мне это сделать?

3 ответа

Решение

Прежде всего, вы можете по умолчанию вы pageSize значение для чего-то:

[HttpGet]
public ActionResult<List<Entry>> GetAll(int? page = null, int? pageSize = 10) 
{
    if (!page.HasValue) {
        return _context.Entries.ToList();
    }

    // do you pagination here
}

Но вы также можете посмотреть на OData, похоже, это ваш случай. Это позволит вам запрашивать ваши данные, используя http-параметры, например: /api/Entires?$skip=5&$top=5

Существуют библиотеки, такие как X.PagedList, которые вы можете использовать. Честно говоря, нумерация страниц довольно проста, так что вам это может даже не понадобиться. Все, что вам нужно знать, это номер страницы, размер страницы и общее количество результатов. Номер страницы очевиден из запроса, и размер страницы может также, если вы хотите, чтобы он настраивался, или вы могли жестко его кодировать.

public ActionResult<List<Entry>> GetAll(int page = 1, int size = 10)

Затем вы можете использовать Skip а также Take чтобы получить данные для конкретной страницы:

var query = _context.Entries;
var entries = await query.Skip((page - 1) * size).Take(size).ToListAsync();
var count = await query.CountAsync();

Затем все, что вам нужно знать, это общее количество страниц, которое можно рассчитать просто:

var totalPages = (int)Math.Ceil(count / (float)size);

Исходя из этого, вы можете рассчитать все, что вам нужно, то есть:

var firstPage = 1; // obviously
var lastPage = totalPages;
var prevPage = page > firstPage ? page - 1 : firstPage;
var nextPage = page < lastPage ? page + 1 : lastPage;

Я только что создал PagingTagHelper для страниц ASP.NET Core Razor, чтобы легко визуализировать управление подкачкой с помощью только основных параметров. Самая простая настройка выглядит следующим образом:

<paging total-records="Model.TotalRecords" page-no="Model.PageNo">
</paging>

все, что вам нужно, это предоставить общее количество записей и номер страницы для его запуска. Параметры строки запроса по умолчанию: "p" для номера страницы и "s" для размера страницы, однако, это настраиваемый / локализуемый, вы можете изменить все настройки в соответствии с вашими требованиями.

Вы можете установить его из Nuget:

Install-Package LazZiya.TagHelpers -Version 1.0.2

затем вам нужно добавить помощник по тегам в файл _ViewImports.cshtml:

@addTagHelper *, LazZiya.TagHelpers

http://ziyad.info/en/articles/21-Paging_TagHelper_for_ASP_NET_Core

больше документации и живое демо будут доступны в ближайшее время.