Repository navigation
Architecture and Packages
This page describes the layering of the libraries, the dependencies between them, and the responsibilities each one owns. It is the page to read when you are deciding which package to install or where to put your own extension.
The repository ships four NuGet packages built from the src/ folder:
| Project folder | NuGet ID | Assembly | Root namespace | Target frameworks |
|---|---|---|---|---|
src/PagedListResult.DataModels |
RzR.ResultMessage.Pagination.Abstractions |
RzR.ResultMessage.Pagination.Abstractions |
RzR.ResultMessage.Pagination.Abstractions.* |
netstandard2.0 |
src/PagedListResult.Common |
RzR.ResultMessage.Pagination.Core |
RzR.ResultMessage.Pagination.Core |
RzR.ResultMessage.Pagination.Core.* |
netstandard2.0 |
src/PagedListResult |
RzR.ResultMessage.Pagination.EntityFrameworkCore |
RzR.ResultMessage.Pagination.EntityFrameworkCore |
RzR.ResultMessage.Pagination.EntityFrameworkCore.* |
netstandard2.0 (multi-target by EF Core consumer) |
src/PagedListResult.Web |
RzR.ResultMessage.Pagination.AspNetCore |
RzR.ResultMessage.Pagination.AspNetCore |
RzR.ResultMessage.Pagination.AspNetCore.* |
netstandard2.1; net5.0; net6.0; net7.0; net8.0; net9.0 |
There is no hidden circular dependency between them; the graph is strictly bottom-up:
DataModels <- Common <- PagedListResult (EF Core) <- PagedListResult.Web (ASP.NET Core)
Pure DTOs. The package contains no logic at all, only:
- Request models:
PagedRequest,PageRequestWithFilters,DataFilter,DataFilterValue,DataFilterDependence,DataOrderDefinition,DataSearchDefinition,DataPredefinedFilterDefinition,DefaultPrimaryKeyDefinition. - Result models:
PagedResult<T>,PagedExecDetailsResult. - Abstractions:
IPagedResult<TSource>(extendsIResult<IList<TSource>>fromRzR.ResultMessage). - Enums:
FilterType,FilterConditionType,OrderDirection.
The package is netstandard2.0, so it can be consumed by .NET Framework, Mono, Xamarin or any .NET 5+ target. Use it when you only need to share the contract with a client (Blazor WASM, Angular client generated from OpenAPI, JS/TS SPA with hand-written types, etc.) without dragging EF Core or ASP.NET Core along.
The expression-builder layer. Built on top of System.Linq.Expressions, it converts the DTOs above into Expression<Func<T, bool>> predicates and IOrderedQueryable<T> ordering. Highlights:
-
FilterSourceByTextExpressionfor free-text search across all text columns or a custom subset. -
FilterSourceOrderExtensionsfor property-name based ordering with optional default-property fallback. -
FilterSourceQueryExtensionsfor the filter pipeline (And/Or, dependencies). -
FilterPredefinedTopRecordExtensionsandPredefinedRecordsHelperfor the "pin top X rows" feature. - Attributes:
-
[PaginationDefaultOrderProperty]— marks a property as the implicit order target when the request asks for default ordering. -
[PaginationDefaultTopRecordPrimaryKey]— marks the property used to match predefined record identifiers when no explicit field is provided.
-
-
ReflectionTypeStorageand friends — small reflection caches used by the builders.
The package has no EF Core dependency. You can use it with plain LINQ-to-Objects, with IQueryable<T> from any provider, or as a low-level building block in your own custom adapter.
This is the package that you most often install directly. It exposes IQueryable<T> extension methods through the static PaginatedQueryExtensions class:
| Method | Purpose |
|---|---|
GetPaged(page, pageSize) |
Plain pagination. |
GetPaged(request, defaultPrimaryKey?) |
Pagination + search + ordering + projection + predefined records. |
GetPagedAsync(page, pageSize, ct) |
Async variant of the simple form. |
GetPagedAsync(request, defaultPrimaryKey?, ct) |
Async variant with PagedRequest. |
GetPagedWithMainFiltersAsync(request, defaultPrimaryKey?, ct) |
Adds top-level AND filtering from PageRequestWithFilters.Filters. |
GetPagedWithFiltersAsync(request, defaultPrimaryKey?, filterLink?, ct) |
Full filter pipeline including dependencies. |
It also includes the SOAP/XML adapters (ToSoapXmlPagedResult on both PagedResult<T> and IPagedResult<T>) used by the Web integration when an XML response is requested.
The package's only third-party runtime dependency is Microsoft.EntityFrameworkCore because of ToListAsync and the DbContext probing used by DefaultPrimaryKeyDefinition discovery. If you do not want EF Core, stay on PagedListResult.Common and write the page slicing yourself.
The ASP.NET Core integration. It is structured around four service surfaces:
-
Configuration (
AddPagedListResultWeb,AddPagedListResultApiExplorer,WithPagedResult/AddPagedResultEndpointFilter). -
Bindings (the
[FromPagedQuery]attribute, thePagedRequestModelBinderProvider, and the dual-hostPagedQuery<T>/PagedQueryWithFilters<T>wrappers inRzR.ResultMessage.Pagination.AspNetCore.Query— they bind in MVC via[FromPagedQuery]and in Minimal API viaBindAsync). -
Response shaping (
PagedResultActionFilter,PagedResultEndpointFilter,PagedResponseHeaderWriter,PagedResultsHttpExtensions.ToPagedHttpResult,BaseApiPagedResultController). -
Discoverability (
PagedResultApplicationModelConventionfor OpenAPI/Swagger, thePageableMetadataallow-list and its registry).
Minimal-API features (PagedQuery<T>, PagedQueryWithFilters<T>, PagedResultEndpointFilter, WithPagedResult, ToPagedHttpResult) are guarded by #if NET7_0_OR_GREATER. Targeting netstandard2.1 or net5.0/net6.0 you still get the MVC binder, the action filter, the controller and the OpenAPI convention.
| Folder | Contents |
|---|---|
Abstractions/ |
IPageableMetadataRegistry, IPagedQueryValidation. |
Attributes/ |
[FromPagedQuery] model-binding attribute. |
Builders/ |
PagedListResultBuilder (returned by AddPagedListResultWeb) and PageableMetadataBuilder<T> (returned by ConfigurePageable<T>). |
Configuration/ |
PagedListResultServiceCollectionExtensions, PagedListResultMvcBuilderExtensions, PagedResultEndpointRouteExtensions, PagedResultApplicationModelConvention. |
Extensions/ |
PagedResultsHttpExtensions.ToPagedHttpResult (minimal-API success/failure adapter). |
Filters/ |
PagedResultActionFilter (MVC) and PagedResultEndpointFilter (minimal API). |
Helpers/ |
PagedQueryKeys, PagedRequestQueryParser, PagedResponseHeaderWriter, MinimalApiQueryBinder. |
Query/ |
PagedQuery<TEntity>, PagedQueryWithFilters<TEntity> — dual-host: bind via BindAsync in Minimal API and via [FromPagedQuery] in MVC. |
ModelBinding/ |
PagedRequestModelBinder, PagedRequestModelBinderProvider. |
Models/ |
PageableMetadata, PagedListResultWebOptions, PagedAccessors, PagedParseResult. |
Registries/ |
PageableMetadataRegistry (default singleton implementation). |
BaseApiPagedResultController.cs |
Convenience base class for [ApiController] controllers. |
The non-trivial third-party packages used at runtime are:
-
RzR.ResultMessage— providesResult<T>/IResult<T>and the message envelope, whichPagedResult<T>extends. -
RzR.ResultMessage.Web— providesResultBaseApiController, theIProblemDetailsResultFactoryand the minimal-APIResultToHttpResult.ToHttpResultadapter thatToPagedHttpResultbuilds upon. -
Microsoft.EntityFrameworkCore— used by the EF Core extensions forToListAsyncand DbContext probing.
There are no analyzers, source generators, runtime IL emitters or proxies. All reflection is small, scoped and cached at static initialization.
A few rules of thumb:
- New filter conditions or builders that do not depend on EF Core: extend
PagedListResult.Common. - New
IQueryable<T>methods specific to EF Core (e.g.IncludeMany, projection helpers): extendPagedListResult. - ASP.NET Core add-ons (custom action filters, alternative serializers, OpenAPI tweaks): extend
PagedListResult.Web. Use the existingPagedListResultBuilderto chain registrations. - Brand-new request shapes that you only consume internally: derive from
PagedRequestorPageRequestWithFiltersinstead of forking the model. The library is generic overTPageRequest : PagedRequest.
PagedListResult is maintained by RzR. GitHub repository.
Start here
Reference
- Data Models Reference
- Expression Builders (Common)
- EntityFramework Core Extensions
- Query String Syntax
ASP.NET Core integration
- Web Integration Overview
- MVC Integration
- Minimal API Integration
- Configuration and Options
- Allow List Registry
- Response Headers and ProblemDetails
- OpenAPI and ApiExplorer
Operations