Pagination in APIs with Razor

 Pagination in APIs


Make a PaginationRequest.cs and put this in it:

namespace eShop.Catalog.API.Model;

public record PaginationRequest(int PageSize = 10, int PageIndex = 0);

------------------------------------

namespace eShop.Catalog.API.Model;

public class PaginatedItems<TEntity>(int pageIndex, int pageSize, long count, IEnumerable<TEntity> data) where TEntity : class

{

    public int PageIndex { get; } = pageIndex;

    public int PageSize { get; } = pageSize;

    public long Count { get; } = count;

    public IEnumerable<TEntity> Data { get;} = data;

}

------------------------------------

   Pagination only really applies to the GetAll(), GetItemsByName(), or GetAllByType() methods. Not needed on create, delete, update, or GetById().  

  So in your:

  api.MapGet("/items", GetAllItems);


   you need to implement GetAllItems() as such:

public static async Task<Results<Ok<PaginatedItems<CatalogItem>>, BadRequest<string>>> GetAllItems(

    [AsParameters] PaginationRequest paginationRequest,

    [AsParameters] CatalogServices services)

{

    var pageSize = paginationRequest.PageSize;

    var pageIndex = paginationRequest.PageIndex;

    var totalItems = await services.Context.CatalogItems

        .LongCountAsync();

    var itemsOnPage = await services.Context.CatalogItems

        .OrderBy(c => c.Name)

        .Skip(pageSize * pageIndex)

        .Take(pageSize)

        .ToListAsync();


    return TypedResults.Ok(new PaginatedItems<CatalogItem>(pageIndex, pageSize, totalItems, itemsOnPage));

}

----------------------

CATALOG.RAZOR


@page "/"

@inject NavigationManager Nav

@inject eShop.HybridApp.Services.CatalogService CatalogService


<PageTitle>AdventureWorks</PageTitle>

<SectionContent SectionName="page-header-title">Ready for a new adventure?</SectionContent>

<SectionContent SectionName="page-header-subtitle">Start the season with the latest in clothing and equipment.</SectionContent>


<div class="catalog">

    <eShop.HybridApp.Components.Pages.Catalog.CatalogSearch BrandId="@BrandId" ItemTypeId="@ItemTypeId" />


    @if (catalogResult is null)

    {

        <p>Loading...</p>

    }

    else

    {

        <div>

            <div class="catalog-items">

                @foreach (var item in catalogResult.Data)

                {

                    <CatalogListItem Item="@item" />

                }

            </div>


            <div class="page-links">

                @foreach (var pageIndex in GetVisiblePageIndexes(catalogResult))

                {

                    <NavLink ActiveClass="active-page" Match="@NavLinkMatch.All" href="@Nav.GetUriWithQueryParameter("page", pageIndex == 1 ? null : pageIndex)">@pageIndex</NavLink>

                }

            </div>

        </div>

    }

</div>


@code {

    const int PageSize = 9;


    [SupplyParameterFromQuery]

    public int? Page { get; set; }


    [SupplyParameterFromQuery(Name = "brand")]

    public int? BrandId { get; set; }


    [SupplyParameterFromQuery(Name = "type")]

    public int? ItemTypeId { get; set; }


    CatalogResult? catalogResult;


    static IEnumerable<int> GetVisiblePageIndexes(CatalogResult result)

        => Enumerable.Range(1, (int)Math.Ceiling(1.0 * result.Count / PageSize));


    protected override async Task OnParametersSetAsync()

    {

        catalogResult = await CatalogService.GetCatalogItems(

            Page.GetValueOrDefault(1) - 1,

            PageSize,

            BrandId,

            ItemTypeId);

    }

}

 


Comments

Popular posts from this blog

Upgrading to .NET8 from desktop versions 4.8.X

GHL Chat Bots for Webpage

GHL > Set website so shorter URL address