From 602771a1c6535ca7a1060aeef91593dd419e05f7 Mon Sep 17 00:00:00 2001 From: Erlend Ellefsen Date: Wed, 6 May 2026 15:11:15 +0200 Subject: [PATCH] refactor(controller): extract EnforceStrictPagination from JsonApiQueryAsync --- .../Controllers/JsonApiController.cs | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/JsonApiToolkit/Controllers/JsonApiController.cs b/JsonApiToolkit/Controllers/JsonApiController.cs index 76a5671..3564661 100644 --- a/JsonApiToolkit/Controllers/JsonApiController.cs +++ b/JsonApiToolkit/Controllers/JsonApiController.cs @@ -206,25 +206,7 @@ string resourceType int totalCount = await filteredQuery.CountAsync().ConfigureAwait(false); LogCountResults(parameters, totalCount); - if (Options.StrictPagination && parameters.Pagination != null && totalCount > 0) - { - int totalPages = (int)Math.Ceiling(totalCount / (double)parameters.Pagination.Size); - if (parameters.Pagination.Number > totalPages) - { - throw new JsonApiNotFoundException( - $"Page {parameters.Pagination.Number} does not exist. " - + $"This collection has {totalPages} page(s). Request a page between 1 and {totalPages}.", - JsonApiErrorCodes.InvalidPageNumber, - new ErrorSource { Parameter = "page[number]" }, - new Dictionary - { - ["value"] = parameters.Pagination.Number, - ["totalPages"] = totalPages, - ["totalResources"] = totalCount, - } - ); - } - } + EnforceStrictPagination(Options, parameters, totalCount); if (parameters.Pagination != null) filteredQuery = filteredQuery.ApplyPagination(parameters.Pagination, totalCount); @@ -241,7 +223,7 @@ string resourceType parameters.Pagination?.Size ?? totalCount ); - IActionResult? projectionResult = await TryApplyDatabaseProjection( + IActionResult? projectionResult = await TryApplyDatabaseProjectionAsync( filteredQuery, resourceType, baseUrl, @@ -511,6 +493,33 @@ List mappedIncludes return filteredQuery; } + private static void EnforceStrictPagination( + JsonApiOptions options, + QueryParameters parameters, + int totalCount + ) + { + if (!options.StrictPagination || parameters.Pagination is null || totalCount == 0) + return; + + int totalPages = (int)Math.Ceiling(totalCount / (double)parameters.Pagination.Size); + if (parameters.Pagination.Number <= totalPages) + return; + + throw new JsonApiNotFoundException( + $"Page {parameters.Pagination.Number} does not exist. " + + $"This collection has {totalPages} page(s). Request a page between 1 and {totalPages}.", + JsonApiErrorCodes.InvalidPageNumber, + new ErrorSource { Parameter = "page[number]" }, + new Dictionary + { + ["value"] = parameters.Pagination.Number, + ["totalPages"] = totalPages, + ["totalResources"] = totalCount, + } + ); + } + private void LogCountResults(QueryParameters parameters, int totalCount) { if (totalCount == 0 && parameters.Filter?.Filters?.Count > 0) @@ -526,7 +535,7 @@ private void LogCountResults(QueryParameters parameters, int totalCount) } } - private async Task TryApplyDatabaseProjection( + private async Task TryApplyDatabaseProjectionAsync( IQueryable filteredQuery, string resourceType, string baseUrl,