diff --git a/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagedList.cs b/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagedList.cs index c09aa9d..c53c23c 100644 --- a/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagedList.cs +++ b/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagedList.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; @@ -12,7 +12,7 @@ public record PagedList /// 创建一个空的 实例。 /// public PagedList() - : this(new List()) + : this([]) { } @@ -86,4 +86,4 @@ public PagedList(IReadOnlyCollection items) /// 元素总数。 /// public int TotalCount { get; init; } -} \ No newline at end of file +} diff --git a/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagingParams.cs b/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagingParams.cs index ac2e3c3..e505c45 100644 --- a/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagingParams.cs +++ b/src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagingParams.cs @@ -1,6 +1,7 @@ -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; namespace Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; @@ -26,13 +27,27 @@ public override string ToString() { const string pageIndexKey = "pageIndex"; const string pageSizeKey = "pageSize"; - var hasPageIndex = int.TryParse(context.Request.Query[pageIndexKey], out var pageIndex); - var hasPageSize = int.TryParse(context.Request.Query[pageSizeKey], out var pageSize); - if (hasPageIndex && hasPageSize && pageIndex > 0 && pageSize >= 0) + + var routeValues = context.GetRouteData().Values; + object? pageSizeValue = null; + var inRouteValues = + routeValues.TryGetValue(pageIndexKey, out var pageIndexValue) && + routeValues.TryGetValue(pageSizeKey, out pageSizeValue); + + if (inRouteValues == false) + { + pageIndexValue = context.Request.Query[pageIndexKey]; + pageSizeValue = context.Request.Query[pageSizeKey]; + } + + if (pageIndexValue != null && + pageSizeValue != null && + int.TryParse(pageIndexValue.ToString(), out var pageIndex) && + int.TryParse(pageSizeValue.ToString(), out var pageSize)) { return ValueTask.FromResult(new PagingParams(pageIndex, pageSize)); } return ValueTask.FromResult(null); } -} \ No newline at end of file +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs index 5acaa26..f2c43df 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs @@ -6,14 +6,18 @@ namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; public class ListArticlesQueryHandler : IPageableQueryHandler { - /// - public Task> Handle(ListArticlesQuery request, CancellationToken cancellationToken) - { - return Task.FromResult(new PagedList([new ArticleDto + private static readonly ArticleDto[] Articles = + [ + new ArticleDto { Id = 1, Title = "作为一个高中生开发者,我的所思所想" } - ])); + ]; + + /// + public Task> Handle(ListArticlesQuery request, CancellationToken cancellationToken) + { + return Task.FromResult(new PagedList(Articles, request.PagingParams, Articles.Length)); } } diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs index 7523e41..e9a1547 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs @@ -40,6 +40,7 @@ => await Task.FromResult(new GetStringQuery(StringId: stringId, Found: found))); v1.MapQuery("strings"); v1.MapQuery("articles"); +v1.MapQuery("articles/page:{pageIndex}-{pageSize}"); v1.MapQuery("long-to-string/{id:long}"); v1.MapCommand("long-to-string"); v1.MapCommand( diff --git a/test/Cnblogs.Architecture.IntegrationTests/PaginationTests.cs b/test/Cnblogs.Architecture.IntegrationTests/PaginationTests.cs new file mode 100644 index 0000000..49a5978 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTests/PaginationTests.cs @@ -0,0 +1,24 @@ +using Cnblogs.Architecture.IntegrationTestProject; +using Microsoft.AspNetCore.Mvc.Testing; + +namespace Cnblogs.Architecture.IntegrationTests; + +public class PaginationTests +{ + [Fact] + public async Task BindPagenationFromRouteValues_SucceedAsync() + { + // Arrange + var builder = new WebApplicationFactory(); + int pageIndex = 1, pageSize = 10; + + // Act + var response = await builder.CreateClient().GetAsync($"/api/v1/articles/page:{pageIndex}-{pageSize}"); + var content = await response.Content.ReadAsStringAsync(); + + // Assert + Assert.True(response.IsSuccessStatusCode); + Assert.Contains($"\"pageIndex\":{pageIndex}", content); + Assert.Contains($"\"pageSize\":{pageSize}", content); + } +}