Skip to content

Janzen.PaginationPagination that stays a contract

Declare once per entity what clients may sort, search and filter. The engine turns an opinionated query string into a translated EF Core query, and rejects everything it cannot honour.

Janzen.Pagination

What it looks like

http
GET /products?page=2&limit=25&sortBy=price:DESC&search=widget&filter.status=$in:Active,Draft&filter.price=$btw:10,500

That contract is borrowed from nestjs-paginate (MIT) — the same query parameters, operator names and response envelope.

Versions track the framework: the first component is the .NET / EF Core major the package targets, so this is the 10.x line, pairing with .NET 10 and EF Core 10. Older lines are not maintained in parallel, and release notes live on the Releases page.

This site is versioned — check which copy you are reading

Nothing here describes unreleased code: the site is published when a stable release is, so the root always shows the newest one — and a prerelease you installed with --prerelease may be ahead of what it says. Every released line also keeps its own copy at /v<line>.x/, this one included, and the version picker in the navigation moves between them without losing your place on the page. From 10.1.0 on, the links inside a package README name that package's own line, so a reader arriving from nuget.org lands in the right copy already. The 10.0.x READMEs predate the versioned copies and point here, to the root — if you installed one of those, open /v10.0.x/ from the picker to read what shipped with it.

Within a line the third component only ever adds, so a member can be newer than the package you installed but never gone from it. One that arrived after the line opened carries its version beside its heading —

10.1.0 — so the gap is visible without leaving the page; an unmarked member

predates the line. The Releases page has what each one carried.

Packages

Four packages. The engine works on its own against any IQueryable<T>; the three add-ons build on it and are independent of each other, so take only the ones you need.

PackagePurpose
Janzen.Pagination.EntityFrameworkCoreProvider-agnostic query engine — fluent PaginateConfig<T>, filtering / sorting / search, projection, PaginateAsync.
Janzen.Pagination.PostgreSqlPostgreSQL provider — case-insensitive search via native ILIKE.
Janzen.Pagination.AspNetCoreASP.NET Core integration — query-string model binding, ProblemDetails, links, OpenAPI metadata.
Janzen.Pagination.NodaTimeNodaTime support — filter / sort / project the seven NodaTime value types (incl. InstantDateTimeOffset).

Install

bash
dotnet add package Janzen.Pagination.EntityFrameworkCore
dotnet add package Janzen.Pagination.AspNetCore

Where to go next

The guide is meant to be read in order, but each page stands on its own. Getting started takes it from install to a paginated endpoint returning JSON.

Once it runs, the site splits by what you are doing:

Query-string contractEvery parameter and operator, with the SQL each one produces. The response, the config API, the query composers and the 400 catalogue sit beside it.
CookbookTask-shaped: role-based configs, collection filters, aggregates, non-web callers, indexing, testing, troubleshooting.
IntegrationsWhat changes when you add ASP.NET Core, PostgreSQL, NodaTime, or a type of your own.

Released under the MIT License.