From ad6660b4b5742e875cf09bd5ff604d6361ce8b86 Mon Sep 17 00:00:00 2001 From: Maurits Moeys Date: Thu, 28 Nov 2019 15:05:18 +0100 Subject: [PATCH] fix: #641 --- .../Contracts/IPageService.cs | 16 +++++++--- .../QueryParameterServices/PageService.cs | 31 ++++++++++++++----- .../Server/Builders/LinkBuilder.cs | 10 +++--- .../Services/DefaultResourceService.cs | 6 ++-- test/UnitTests/Builders/LinkBuilderTests.cs | 2 +- .../QueryParameters/PageServiceTests.cs | 2 +- 6 files changed, 45 insertions(+), 22 deletions(-) diff --git a/src/JsonApiDotNetCore/QueryParameterServices/Contracts/IPageService.cs b/src/JsonApiDotNetCore/QueryParameterServices/Contracts/IPageService.cs index 8157ab077f..64f4a9f965 100644 --- a/src/JsonApiDotNetCore/QueryParameterServices/Contracts/IPageService.cs +++ b/src/JsonApiDotNetCore/QueryParameterServices/Contracts/IPageService.cs @@ -6,13 +6,17 @@ namespace JsonApiDotNetCore.Query public interface IPageService : IQueryParameterService { /// - /// What the total records are for this output + /// Gets the requested or default page size /// - int? TotalRecords { get; set; } + int CurrentPageSize { get; } + /// + /// Default size to be used in pagination + /// + int DefaultPageSize { get; set; } /// - /// How many records per page should be shown + /// Currently requested page size to be used in pagination /// - int PageSize { get; set; } + int? RequestedPageSize { get; set; } /// /// The page requested. Note that the page number is one-based. /// @@ -29,5 +33,9 @@ public interface IPageService : IQueryParameterService /// Denotes if pagination is backwards /// bool Backwards { get; } + /// + /// What the total records are for this output + /// + int? TotalRecords { get; set; } } } diff --git a/src/JsonApiDotNetCore/QueryParameterServices/PageService.cs b/src/JsonApiDotNetCore/QueryParameterServices/PageService.cs index b0b099058d..16883f1909 100644 --- a/src/JsonApiDotNetCore/QueryParameterServices/PageService.cs +++ b/src/JsonApiDotNetCore/QueryParameterServices/PageService.cs @@ -13,11 +13,10 @@ namespace JsonApiDotNetCore.Query public class PageService : QueryParameterService, IPageService { private readonly IJsonApiOptions _options; - public PageService(IJsonApiOptions options, IResourceGraph resourceGraph, ICurrentRequest currentRequest) : base(resourceGraph, currentRequest) { _options = options; - PageSize = _options.DefaultPageSize; + DefaultPageSize = _options.DefaultPageSize; } /// @@ -26,14 +25,27 @@ public PageService(IJsonApiOptions options, IResourceGraph resourceGraph, ICurre internal PageService(IJsonApiOptions options) { _options = options; - PageSize = _options.DefaultPageSize; + DefaultPageSize = _options.DefaultPageSize; } /// - public int? TotalRecords { get; set; } + public int CurrentPageSize + { + get + { + if (RequestedPageSize.HasValue) + { + return RequestedPageSize.Value; + } + return DefaultPageSize; + } + } + + /// + public int DefaultPageSize { get; set; } /// - public int PageSize { get; set; } + public int? RequestedPageSize { get; set; } /// public int CurrentPage { get; set; } = 1; @@ -42,17 +54,20 @@ internal PageService(IJsonApiOptions options) public bool Backwards { get; set; } /// - public int TotalPages => (TotalRecords == null || PageSize == 0) ? -1 : (int)Math.Ceiling(decimal.Divide(TotalRecords.Value, PageSize)); + public int TotalPages => (TotalRecords == null || CurrentPageSize == 0) ? -1 : (int)Math.Ceiling(decimal.Divide(TotalRecords.Value, CurrentPageSize)); /// public bool CanPaginate { get { return TotalPages > 1; } } + /// + public int? TotalRecords { get; set; } + /// public virtual void Parse(KeyValuePair queryParameter) { EnsureNoNestedResourceRoute(); // expected input = page[size]= - // page[number]= 0> + // page[number]= var propertyName = queryParameter.Key.Split(QueryConstants.OPEN_BRACKET, QueryConstants.CLOSE_BRACKET)[1]; const string SIZE = "size"; @@ -70,7 +85,7 @@ public virtual void Parse(KeyValuePair queryParameter) } else { - PageSize = size; + RequestedPageSize = size; } } else if (propertyName == NUMBER) diff --git a/src/JsonApiDotNetCore/Serialization/Server/Builders/LinkBuilder.cs b/src/JsonApiDotNetCore/Serialization/Server/Builders/LinkBuilder.cs index 8b195a661a..8fe73a289d 100644 --- a/src/JsonApiDotNetCore/Serialization/Server/Builders/LinkBuilder.cs +++ b/src/JsonApiDotNetCore/Serialization/Server/Builders/LinkBuilder.cs @@ -63,19 +63,19 @@ private void SetPageLinks(ResourceContext primaryResource, TopLevelLinks links) { if (_pageService.CurrentPage > 1) { - links.Prev = GetPageLink(primaryResource, _pageService.CurrentPage - 1, _pageService.PageSize); + links.Prev = GetPageLink(primaryResource, _pageService.CurrentPage - 1, _pageService.CurrentPageSize); } if (_pageService.CurrentPage < _pageService.TotalPages) { - links.Next = GetPageLink(primaryResource, _pageService.CurrentPage + 1, _pageService.PageSize); + links.Next = GetPageLink(primaryResource, _pageService.CurrentPage + 1, _pageService.CurrentPageSize); } if (_pageService.TotalPages > 0) { - links.Self = GetPageLink(primaryResource, _pageService.CurrentPage, _pageService.PageSize); - links.First = GetPageLink(primaryResource, 1, _pageService.PageSize); - links.Last = GetPageLink(primaryResource, _pageService.TotalPages, _pageService.PageSize); + links.Self = GetPageLink(primaryResource, _pageService.CurrentPage, _pageService.CurrentPageSize); + links.First = GetPageLink(primaryResource, 1, _pageService.CurrentPageSize); + links.Last = GetPageLink(primaryResource, _pageService.TotalPages, _pageService.CurrentPageSize); } } diff --git a/src/JsonApiDotNetCore/Services/DefaultResourceService.cs b/src/JsonApiDotNetCore/Services/DefaultResourceService.cs index 86b5a2d976..cb4328947a 100644 --- a/src/JsonApiDotNetCore/Services/DefaultResourceService.cs +++ b/src/JsonApiDotNetCore/Services/DefaultResourceService.cs @@ -200,7 +200,7 @@ public virtual async Task UpdateRelationshipsAsync(TId id, string relationshipNa protected virtual async Task> ApplyPageQueryAsync(IQueryable entities) { - if (!(_pageService.PageSize > 0)) + if (!(_pageService.CurrentPageSize > 0)) { var allEntities = await _repository.ToListAsync(entities); return allEntities as IEnumerable; @@ -214,10 +214,10 @@ protected virtual async Task> ApplyPageQueryAsync(IQuerya if (_logger?.IsEnabled(LogLevel.Information) == true) { _logger?.LogInformation($"Applying paging query. Fetching page {pageOffset} " + - $"with {_pageService.PageSize} entities"); + $"with {_pageService.CurrentPageSize} entities"); } - return await _repository.PageAsync(entities, _pageService.PageSize, pageOffset); + return await _repository.PageAsync(entities, _pageService.CurrentPageSize, pageOffset); } /// diff --git a/test/UnitTests/Builders/LinkBuilderTests.cs b/test/UnitTests/Builders/LinkBuilderTests.cs index 32742560cf..bfb1bc5ff1 100644 --- a/test/UnitTests/Builders/LinkBuilderTests.cs +++ b/test/UnitTests/Builders/LinkBuilderTests.cs @@ -195,7 +195,7 @@ private IPageService GetPageManager() mock.Setup(m => m.CanPaginate).Returns(true); mock.Setup(m => m.CurrentPage).Returns(2); mock.Setup(m => m.TotalPages).Returns(3); - mock.Setup(m => m.PageSize).Returns(10); + mock.Setup(m => m.CurrentPageSize).Returns(10); return mock.Object; } diff --git a/test/UnitTests/QueryParameters/PageServiceTests.cs b/test/UnitTests/QueryParameters/PageServiceTests.cs index 22373d7d86..eafafbcec3 100644 --- a/test/UnitTests/QueryParameters/PageServiceTests.cs +++ b/test/UnitTests/QueryParameters/PageServiceTests.cs @@ -46,7 +46,7 @@ public void Parse_PageSize_CanParse(string value, int expectedValue, bool should else { service.Parse(query); - Assert.Equal(expectedValue, service.PageSize); + Assert.Equal(expectedValue, service.CurrentPageSize); } }