Skip to content

Commit f2d4834

Browse files
committed
feat: bind PagingParams from route values
1 parent 3c217d1 commit f2d4834

File tree

5 files changed

+61
-14
lines changed

5 files changed

+61
-14
lines changed

src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagedList.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System.Text.Json.Serialization;
1+
using System.Text.Json.Serialization;
22

33
namespace Cnblogs.Architecture.Ddd.Infrastructure.Abstractions;
44

@@ -12,7 +12,7 @@ public record PagedList<T>
1212
/// 创建一个空的 <see cref="PagedList{T}" /> 实例。
1313
/// </summary>
1414
public PagedList()
15-
: this(new List<T>())
15+
: this([])
1616
{
1717
}
1818

@@ -86,4 +86,4 @@ public PagedList(IReadOnlyCollection<T> items)
8686
/// 元素总数。
8787
/// </summary>
8888
public int TotalCount { get; init; }
89-
}
89+
}

src/Cnblogs.Architecture.Ddd.Infrastructure.Abstractions/PagingParams.cs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
using System.ComponentModel.DataAnnotations;
1+
using System.ComponentModel.DataAnnotations;
22

33
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.Routing;
45

56
namespace Cnblogs.Architecture.Ddd.Infrastructure.Abstractions;
67

@@ -26,13 +27,30 @@ public override string ToString()
2627
{
2728
const string pageIndexKey = "pageIndex";
2829
const string pageSizeKey = "pageSize";
29-
var hasPageIndex = int.TryParse(context.Request.Query[pageIndexKey], out var pageIndex);
30-
var hasPageSize = int.TryParse(context.Request.Query[pageSizeKey], out var pageSize);
31-
if (hasPageIndex && hasPageSize && pageIndex > 0 && pageSize >= 0)
30+
31+
var routeValues = context.GetRouteData().Values;
32+
object? pageSizeValue = null;
33+
var inRouteValues =
34+
routeValues.TryGetValue(pageIndexKey, out var pageIndexValue) &&
35+
routeValues.TryGetValue(pageSizeKey, out pageSizeValue);
36+
37+
if (inRouteValues == false)
38+
{
39+
pageIndexValue = context.Request.Query[pageIndexKey];
40+
pageSizeValue = context.Request.Query[pageSizeKey];
41+
}
42+
43+
if (pageIndexValue != null &&
44+
pageSizeValue != null &&
45+
int.TryParse(pageIndexValue.ToString(), out var pageIndex) &&
46+
int.TryParse(pageSizeValue.ToString(), out var pageSize))
3247
{
33-
return ValueTask.FromResult<PagingParams?>(new PagingParams(pageIndex, pageSize));
48+
if (pageIndex > 0 && pageSize >= 0)
49+
{
50+
return ValueTask.FromResult<PagingParams?>(new PagingParams(pageIndex, pageSize));
51+
}
3452
}
3553

3654
return ValueTask.FromResult<PagingParams?>(null);
3755
}
38-
}
56+
}

test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@ namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries;
66

77
public class ListArticlesQueryHandler : IPageableQueryHandler<ListArticlesQuery, ArticleDto>
88
{
9-
/// <inheritdoc />
10-
public Task<PagedList<ArticleDto>> Handle(ListArticlesQuery request, CancellationToken cancellationToken)
11-
{
12-
return Task.FromResult(new PagedList<ArticleDto>([new ArticleDto
9+
private static readonly ArticleDto[] Articles =
10+
[
11+
new ArticleDto
1312
{
1413
Id = 1,
1514
Title = "作为一个高中生开发者,我的所思所想"
1615
}
17-
]));
16+
];
17+
18+
/// <inheritdoc />
19+
public Task<PagedList<ArticleDto>> Handle(ListArticlesQuery request, CancellationToken cancellationToken)
20+
{
21+
return Task.FromResult(new PagedList<ArticleDto>(Articles, request.PagingParams, Articles.Length));
1822
}
1923
}

test/Cnblogs.Architecture.IntegrationTestProject/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
=> await Task.FromResult(new GetStringQuery(StringId: stringId, Found: found)));
4141
v1.MapQuery<ListStringsQuery>("strings");
4242
v1.MapQuery<ListArticlesQuery>("articles");
43+
v1.MapQuery<ListArticlesQuery>("articles/page:{pageIndex}-{pageSize}");
4344
v1.MapQuery<GetLongToStringQuery>("long-to-string/{id:long}");
4445
v1.MapCommand<CreateLongToStringCommand>("long-to-string");
4546
v1.MapCommand(
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using Cnblogs.Architecture.IntegrationTestProject;
2+
using Microsoft.AspNetCore.Mvc.Testing;
3+
4+
namespace Cnblogs.Architecture.IntegrationTests;
5+
6+
public class PaginationTests
7+
{
8+
[Fact]
9+
public async Task BindPagenationFromRouteValues_SucceedAsync()
10+
{
11+
// Arrange
12+
var builder = new WebApplicationFactory<Program>();
13+
int pageIndex = 1, pageSize = 10;
14+
15+
// Act
16+
var response = await builder.CreateClient().GetAsync($"/api/v1/articles/page:{pageIndex}-{pageSize}");
17+
var content = await response.Content.ReadAsStringAsync();
18+
19+
// Assert
20+
Assert.True(response.IsSuccessStatusCode);
21+
Assert.Contains($"\"pageIndex\":{pageIndex}", content);
22+
Assert.Contains($"\"pageSize\":{pageSize}", content);
23+
}
24+
}

0 commit comments

Comments
 (0)