From 485ae7cfc0d761f806c3fca97283a02920c2f079 Mon Sep 17 00:00:00 2001 From: rikolearn Date: Mon, 24 Apr 2023 13:51:18 +0330 Subject: [PATCH] add pagination for repository and response message --- ....Commons.PresentationInfrastructure.csproj | 1 + .../Converters/JsonForceDefaultConverter.cs | 19 ++++++++++ .../Responses/GenericResponseBase.cs | 9 +++++ .../GenericResponseBaseWithPagination.cs | 7 ++++ .../Responses/PaginationMetadata.cs | 13 +++++++ .../Responses/Response.cs | 19 ++++++++++ .../BSN.Commons/Dto/PagedEntityCollection.cs | 36 +++++++++++++++++++ .../Extensions/IQueryableExtensions.cs | 30 ++++++++++++++++ 8 files changed, 134 insertions(+) create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs create mode 100644 Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs create mode 100644 Source/BSN.Commons/Dto/PagedEntityCollection.cs create mode 100644 Source/BSN.Commons/Extensions/IQueryableExtensions.cs diff --git a/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj b/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj index eccb3bc..dda0e7f 100644 --- a/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj +++ b/Source/BSN.Commons.PresentationInfrastructure/BSN.Commons.PresentationInfrastructure.csproj @@ -17,6 +17,7 @@ + diff --git a/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs new file mode 100644 index 0000000..302035e --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Converters/JsonForceDefaultConverter.cs @@ -0,0 +1,19 @@ +using System; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace BSN.Commons.Converters +{ + public class JsonForceDefaultConverter : JsonConverter + { + public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + return JsonSerializer.Deserialize(ref reader); + } + + public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) + { + JsonSerializer.Serialize(writer, value); + } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs new file mode 100644 index 0000000..fc92f1a --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBase.cs @@ -0,0 +1,9 @@ +namespace BSN.Commons.Responses +{ + public class GenericResponseBase : Response where T : class + { + public T Data { get; set; } + + public GenericResponseBase() { } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs new file mode 100644 index 0000000..94bce8d --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/GenericResponseBaseWithPagination.cs @@ -0,0 +1,7 @@ +namespace BSN.Commons.Responses +{ + public class GenericResponseBaseWithPagination : GenericResponseBase where T : class + { + public PaginationMetadata Meta { get; set; } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs new file mode 100644 index 0000000..1cfd739 --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/PaginationMetadata.cs @@ -0,0 +1,13 @@ +namespace BSN.Commons.Responses +{ + public class PaginationMetadata + { + public uint Page { get; set; } + + public uint PageCount { get; set; } + + public uint PageSize { get; set; } + + public uint RecordCount { get; set; } + } +} diff --git a/Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs b/Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs new file mode 100644 index 0000000..3524f93 --- /dev/null +++ b/Source/BSN.Commons.PresentationInfrastructure/Responses/Response.cs @@ -0,0 +1,19 @@ +using BSN.Commons.Converters; +using BSN.Commons.PresentationInfrastructure; +using System.Text.Json.Serialization; + +namespace BSN.Commons.Responses +{ + /// + /// During serialization and deserialization operations, enumeration values are always converted to and from strings. + /// This is possible through registering the 'JsonStringEnumConverter' in our DI infrastructure. There is once exception, + /// namely the 'StatusCode' property of the 'ResponseBase' class which should keep it's default numeral value when being converted. + /// + public class Response : ResponseBase + { + public new bool IsSuccess => (int)StatusCode >= 200 && (int)StatusCode <= 299; + + [JsonConverter(typeof(JsonForceDefaultConverter))] + public new ResponseStatusCode StatusCode { get; set; } + } +} diff --git a/Source/BSN.Commons/Dto/PagedEntityCollection.cs b/Source/BSN.Commons/Dto/PagedEntityCollection.cs new file mode 100644 index 0000000..5b3c28c --- /dev/null +++ b/Source/BSN.Commons/Dto/PagedEntityCollection.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; + +namespace BSN.Commons.Dto +{ + /// + /// Stores the paginated data for the given entity type. + /// + /// Type of Entity for which pagination is being implemented. + public class PagedEntityCollection + { + /// + /// Current page number + /// + public uint CurrentPage { get; set; } + + /// + /// Total number of pages + /// + public uint PageCount { get; set; } + + /// + /// Number of records per page + /// + public uint PageSize { get; set; } + + /// + /// Total number of records that exist for the query + /// + public uint RecordCount { get; set; } + + /// + /// IEnumerable of the paginated data + /// + public IEnumerable Results { get; set; } + } +} diff --git a/Source/BSN.Commons/Extensions/IQueryableExtensions.cs b/Source/BSN.Commons/Extensions/IQueryableExtensions.cs new file mode 100644 index 0000000..b1bf084 --- /dev/null +++ b/Source/BSN.Commons/Extensions/IQueryableExtensions.cs @@ -0,0 +1,30 @@ +using BSN.Commons.Dto; +using System; +using System.Linq; + +namespace BSN.Commons.Extensions +{ + public static partial class IQueryableExtensions + { + public static PagedEntityCollection Paginate(this IQueryable query, uint pageNumber, uint pageSize) + { + if (pageNumber == 0) + throw new ArgumentException("Must be greater than zero.", nameof(pageNumber)); + + if (pageSize == 0) + throw new ArgumentException("Must be greater than zero.", nameof(pageSize)); + + var result = new PagedEntityCollection + { + CurrentPage = pageNumber, + PageSize = pageSize, + RecordCount = (uint)query.Count(), + Results = query.Skip((int)((pageNumber - 1) * pageSize)).Take((int)pageSize).ToList() + }; + + result.PageCount = (uint)Math.Ceiling((double)result.RecordCount / pageSize); + + return result; + } + } +}