C0deGeek.Pagination
1.1.0
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package C0deGeek.Pagination --version 1.1.0
NuGet\Install-Package C0deGeek.Pagination -Version 1.1.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="C0deGeek.Pagination" Version="1.1.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add C0deGeek.Pagination --version 1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: C0deGeek.Pagination, 1.1.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install C0deGeek.Pagination as a Cake Addin #addin nuget:?package=C0deGeek.Pagination&version=1.1.0 // Install C0deGeek.Pagination as a Cake Tool #tool nuget:?package=C0deGeek.Pagination&version=1.1.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
C0deGeek.Pagination
A comprehensive pagination solution for ASP.NET Core applications offering two implementations:
- Full version with Entity Framework Core integration
- Light version for any IQueryable/IEnumerable
Table of Contents
- Features
- Installation
- Full Version (EF Core)
- Light Version
- Configuration Options
- Advanced Features
- Best Practices
- Contributing
- License
- Acknowledgments
Features
Full Version (EF Core)
- ✨ Entity Framework Core integration
- 🔒 Concurrency control with RowVersion
- 💪 Circuit breaker and retry policies
- 🌡️ Rate limiting (service and API level)
- 📦 Advanced caching strategies
Light Version
- 🚀 Works with any IQueryable/IEnumerable
- 📦 No database dependencies
- ⚡ Lightweight and fast
- 🗃️ Simple memory caching
- 🔄 Dynamic sorting
Common Features (Both Versions)
- 🔍 Flexible search capabilities
- 🗜️ Response compression
- 📦 ETag support
- 🔄 HATEOAS support
- 🛡️ Thread-safe operations
Installation
dotnet add package C0deGeek.Pagination
Full Version (EF Core)
Quick Start
- Define your entity:
public class User : IEntity
{
public int Id { get; set; }
public required string? Name { get; set; }
public required string? Email { get; set; }
public required byte[] RowVersion { get; set; }
public DateTime LastModified { get; set; }
public DateTime CreatedAt { get; set; }
public bool IsActive { get; set; }
}
- Set up your DbContext:
public class YourDbContext : PaginationDbContext<YourDbContext>
{
public DbSet<User> Users => Set<User>();
public YourDbContext(DbContextOptions<YourDbContext> options)
: base(options)
{
}
}
- Register services:
services.AddPagination<YourDbContext>(options =>
{
options.EnableCaching = true;
options.CacheSlidingExpiration = TimeSpan.FromMinutes(5);
options.EnableRateLimiting = true;
options.RateLimitPermitLimit = 100;
});
- Create your controller:
[ApiController]
[Route("api/[controller]")]
public class UsersController : PaginationControllerBase<User>
{
private readonly PaginationService<User, YourDbContext> _paginationService;
public UsersController(PaginationService<User, YourDbContext> paginationService)
{
_paginationService = paginationService;
}
[HttpGet]
[EnableRateLimiting("fixed")]
public async Task<IActionResult> GetUsers(
[FromQuery] PaginationParameters parameters,
[FromHeader(Name = "If-None-Match")] string? ifNoneMatch = null,
CancellationToken cancellationToken = default)
{
var result = await _paginationService.GetPagedDataAsync(
parameters,
cancellationToken);
if (result is null)
{
return StatusCode(304);
}
return Ok(new PaginationResponse<User>(
result.Items,
result,
GenerateLinks(result, nameof(GetUsers), new { parameters.PageSize })
));
}
}
Light Version
Quick Start
- Define your model:
public class Item : ILightSearchable
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool MatchesSearchTerm(string searchTerm)
{
return Name.Contains(searchTerm, StringComparison.OrdinalIgnoreCase) ||
Description.Contains(searchTerm, StringComparison.OrdinalIgnoreCase);
}
}
- Register services:
services.AddLightPagination(options =>
{
options.EnableCompression = true;
options.EnableResponseCaching = true;
options.EnableCaching = true;
options.EnableDynamicSorting = true;
});
- Create your controller:
[ApiController]
[Route("api/[controller]")]
public class ItemsController : LightPaginationControllerBase
{
private readonly LightPaginationService _paginationService;
private readonly LightPaginationOptions _options;
public ItemsController(
LightPaginationService paginationService,
IOptions<LightPaginationOptions> options)
{
_paginationService = paginationService;
_options = options.Value;
}
[HttpGet]
public async Task<IActionResult> GetItems(
[FromQuery] LightPaginationParameters parameters,
CancellationToken cancellationToken)
{
var items = GetItems(); // Your data source
var result = await _paginationService.CreatePaginatedResultAsync(
items,
parameters,
cancellationToken);
return await CreatePaginatedResponseAsync(
result,
_options,
nameof(GetItems),
new { parameters.PageSize });
}
}
Configuration Options
Full Version Options
services.AddPagination<YourDbContext>(options =>
{
// Caching
options.EnableCaching = true;
options.CacheSlidingExpiration = TimeSpan.FromMinutes(5);
options.CacheAbsoluteExpiration = TimeSpan.FromHours(1);
// Rate Limiting
options.EnableRateLimiting = true;
options.RateLimitPermitLimit = 100;
options.RateLimitWindowSeconds = 1;
// Circuit Breaker
options.CircuitBreakerFailureThreshold = 5;
options.CircuitBreakerSamplingDuration = TimeSpan.FromSeconds(30);
options.CircuitBreakerDurationOfBreak = TimeSpan.FromSeconds(60);
// Retry Policy
options.RetryCount = 3;
options.RetryBaseDelayMs = 100;
// Database
options.IsolationLevel = IsolationLevel.ReadCommitted;
});
Light Version Options
services.AddLightPagination(options =>
{
// Caching
options.EnableCaching = true;
options.CacheSlidingExpiration = TimeSpan.FromMinutes(5);
options.CacheAbsoluteExpiration = TimeSpan.FromHours(1);
// Compression
options.EnableCompression = true;
options.CompressionLevel = CompressionLevel.Optimal;
// Response Caching
options.EnableResponseCaching = true;
options.ResponseCacheDuration = 60;
// Pagination
options.MaxPageSize = 100;
options.DefaultPageSize = 10;
// Sorting
options.EnableDynamicSorting = true;
});
Response Format
Both versions return responses in this format:
{
"data": [
{
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"isActive": true
}
],
"pagination": {
"currentPage": 1,
"pageSize": 10,
"totalPages": 5,
"totalItems": 48,
"hasNextPage": true,
"hasPreviousPage": false,
"links": [
{
"href": "/api/items?pageNumber=1&pageSize=10",
"rel": "self",
"method": "GET"
},
{
"href": "/api/items?pageNumber=2&pageSize=10",
"rel": "next",
"method": "GET"
}
]
}
}
When to Use Which Version?
Use Full (EF Core) Version When:
- You're using Entity Framework Core
- You need concurrency control
- You need database-level transactions
- You require circuit breaker patterns
- You want retry policies for database operations
Use Light Version When:
- You're working with in-memory collections
- You're using a different ORM
- You need simple pagination without database dependencies
- You want faster performance for small datasets
- You're paginating API responses from other services
Best Practices
- Always use cancellation tokens for async operations
- Implement proper error handling
- Set appropriate cache durations
- Configure compression based on response size
- Use appropriate isolation levels (Full version)
- Monitor memory usage with caching
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature
) - Commit your changes (
git commit -m 'Add some AmazingFeature'
) - Push to the branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE.md file for details
Acknowledgments
- Built with ASP.NET Core
- Uses Polly for resilience patterns (Full version)
- Inspired by REST best practices and HATEOAS principles
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Microsoft.AspNetCore.Http.Abstractions (>= 2.2.0)
- Microsoft.EntityFrameworkCore (>= 8.0.10)
- Microsoft.EntityFrameworkCore.Relational (>= 8.0.10)
- Microsoft.EntityFrameworkCore.SqlServer (>= 8.0.10)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Polly (>= 8.4.2)
- System.Threading.RateLimiting (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.