diff --git a/src/MaksIT.Core/Abstractions/Webapi/RequestModelBase.cs b/src/MaksIT.Core/Abstractions/Webapi/RequestModelBase.cs
new file mode 100644
index 0000000..c195bd5
--- /dev/null
+++ b/src/MaksIT.Core/Abstractions/Webapi/RequestModelBase.cs
@@ -0,0 +1,9 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MaksIT.Core.Abstractions.Webapi;
+public abstract class RequestModelBase {
+}
diff --git a/src/MaksIT.Core/Abstractions/Webapi/ResponseModelBase.cs b/src/MaksIT.Core/Abstractions/Webapi/ResponseModelBase.cs
new file mode 100644
index 0000000..0be10f8
--- /dev/null
+++ b/src/MaksIT.Core/Abstractions/Webapi/ResponseModelBase.cs
@@ -0,0 +1,9 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MaksIT.Core.Abstractions.Webapi;
+public abstract class ResponseModelBase {
+}
diff --git a/src/MaksIT.Core/MaksIT.Core.csproj b/src/MaksIT.Core/MaksIT.Core.csproj
index 043bb78..d6232ba 100644
--- a/src/MaksIT.Core/MaksIT.Core.csproj
+++ b/src/MaksIT.Core/MaksIT.Core.csproj
@@ -8,7 +8,7 @@
MaksIT.Core
- 1.0.8
+ 1.0.9
Maksym Sadovnychyy
MAKS-IT
MaksIT.Core
diff --git a/src/MaksIT.Core/Webapi/Models/PagedRequest.cs b/src/MaksIT.Core/Webapi/Models/PagedRequest.cs
new file mode 100644
index 0000000..2fa78ac
--- /dev/null
+++ b/src/MaksIT.Core/Webapi/Models/PagedRequest.cs
@@ -0,0 +1,118 @@
+using System.Linq.Expressions;
+
+using MaksIT.Core.Abstractions.Webapi;
+
+namespace MaksIT.Core.Webapi.Models;
+public abstract class PagedRequest : RequestModelBase {
+ public int PageSize { get; set; } = 100;
+ public int PageNumber { get; set; } = 1;
+
+ // Global filter applicable to any collection
+ public string? Filters { get; set; }
+
+ // Specific filters for different collections
+ public Dictionary? CollectionFilters { get; set; }
+
+ // Optional sorting
+ public string? SortBy { get; set; }
+ public bool IsAscending { get; set; } = true;
+
+ // Method to build an expression for a specific collection, combining global and collection-specific filters
+ public Expression> BuildCollectionFilterExpression(string collectionName) {
+ var expressions = new List();
+
+ var parameter = Expression.Parameter(typeof(T), "x");
+
+ // Add global filters if available
+ if (!string.IsNullOrEmpty(Filters)) {
+ var globalFilterExpression = BuildFilterExpression(Filters, parameter);
+ expressions.Add(globalFilterExpression);
+ }
+
+ // Add collection-specific filters if available
+ if (CollectionFilters != null && CollectionFilters.ContainsKey(collectionName) && !string.IsNullOrEmpty(CollectionFilters[collectionName])) {
+ var collectionFilterExpression = BuildFilterExpression(CollectionFilters[collectionName], parameter);
+ expressions.Add(collectionFilterExpression);
+ }
+
+ // Combine the expressions using AND (you can extend to OR logic if needed)
+ Expression combinedExpression;
+ if (expressions.Any()) {
+ combinedExpression = expressions.Aggregate(Expression.AndAlso);
+ }
+ else {
+ // Default to 'true' if no filters are provided
+ combinedExpression = Expression.Constant(true);
+ }
+
+ return Expression.Lambda>(combinedExpression, parameter);
+ }
+
+ // Method to build a LINQ expression from a single filter string (global or collection-specific)
+ public Expression> BuildFilterExpression(string filter, ParameterExpression? parameter = null) {
+ if (string.IsNullOrEmpty(filter))
+ return x => true; // Default to 'true' if no filters are provided
+
+ parameter ??= Expression.Parameter(typeof(T), "x");
+ var expressions = new List();
+
+ // Parse the filters string (this logic can be extended to support more complex filtering)
+ var filters = filter.Split(new[] { "AND", "OR" }, StringSplitOptions.None);
+
+ foreach (var subFilter in filters) {
+ if (subFilter.Contains('=')) {
+ var parts = subFilter.Split('=');
+ var propertyName = parts[0].Trim();
+ var value = parts[1].Trim().Replace("'", "");
+
+ var property = Expression.Property(parameter, propertyName);
+ var constant = Expression.Constant(ConvertValue(property.Type, value));
+
+ expressions.Add(Expression.Equal(property, constant));
+ }
+ else if (subFilter.Contains('>') || subFilter.Contains('<')) {
+ var comparisonType = subFilter.Contains(">=") ? ">=" :
+ subFilter.Contains("<=") ? "<=" :
+ subFilter.Contains(">") ? ">" : "<";
+ var parts = subFilter.Split(new[] { '>', '<', '=', ' ' }, StringSplitOptions.RemoveEmptyEntries);
+ var propertyName = parts[0].Trim();
+ var value = parts[1].Trim().Replace("'", "");
+
+ var property = Expression.Property(parameter, propertyName);
+ var constant = Expression.Constant(ConvertValue(property.Type, value));
+
+ switch (comparisonType) {
+ case ">":
+ expressions.Add(Expression.GreaterThan(property, constant));
+ break;
+ case "<":
+ expressions.Add(Expression.LessThan(property, constant));
+ break;
+ case ">=":
+ expressions.Add(Expression.GreaterThanOrEqual(property, constant));
+ break;
+ case "<=":
+ expressions.Add(Expression.LessThanOrEqual(property, constant));
+ break;
+ }
+ }
+ }
+
+ // Combine the expressions using AND (you can extend to support OR)
+ var combinedExpression = expressions.Aggregate(Expression.AndAlso);
+
+ return Expression.Lambda>(combinedExpression, parameter);
+ }
+
+ // Helper method to convert the value to the correct type
+ private static object ConvertValue(Type type, string value) {
+ if (type == typeof(int))
+ return int.Parse(value);
+ if (type == typeof(bool))
+ return bool.Parse(value);
+ if (type == typeof(DateTime))
+ return DateTime.Parse(value);
+
+ return value; // Default to string
+ }
+}
diff --git a/src/MaksIT.Core/Webapi/Models/PagedResponse.cs b/src/MaksIT.Core/Webapi/Models/PagedResponse.cs
new file mode 100644
index 0000000..8f1e49f
--- /dev/null
+++ b/src/MaksIT.Core/Webapi/Models/PagedResponse.cs
@@ -0,0 +1,20 @@
+using MaksIT.Core.Abstractions.Webapi;
+
+namespace MaksIT.Core.Webapi.Models;
+
+public class PagedResponse : ResponseModelBase {
+ public IEnumerable Items { get; set; }
+ public int PageNumber { get; set; }
+ public int PageSize { get; set; }
+ public int TotalCount { get; set; }
+ public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize);
+ public bool HasPreviousPage => PageNumber > 1;
+ public bool HasNextPage => PageNumber < TotalPages;
+
+ public PagedResponse(IEnumerable items, int totalCount, int pageNumber, int pageSize) {
+ Items = items;
+ TotalCount = totalCount;
+ PageNumber = pageNumber;
+ PageSize = pageSize;
+ }
+}
\ No newline at end of file