From fde75c19fe132657ef8e4f347bc5b22c9c37b8ae Mon Sep 17 00:00:00 2001 From: dudu Date: Tue, 7 Oct 2025 17:04:09 +0800 Subject: [PATCH 1/2] test: add test case to reproduce encoded Chinese characters --- .../Application/Queries/ListArticlesQuery.cs | 7 ++++++ .../Queries/ListArticlesQueryHandler.cs | 19 +++++++++++++++ .../Application/Queries/ListStringsQuery.cs | 4 ++-- .../Queries/ListStringsQueryHandler.cs | 4 ++-- .../Models/ArticleDto.cs | 7 ++++++ .../Program.cs | 3 ++- .../MinimalApiTests.cs | 24 +++++++++++++++++++ 7 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQuery.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTestProject/Models/ArticleDto.cs create mode 100644 test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQuery.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQuery.cs new file mode 100644 index 0000000..898f5fc --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQuery.cs @@ -0,0 +1,7 @@ +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; +using Cnblogs.Architecture.IntegrationTestProject.Models; + +namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; + +public record ListArticlesQuery(PagingParams? PagingParams, string? OrderByString) : IPageableQuery; diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs new file mode 100644 index 0000000..5acaa26 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListArticlesQueryHandler.cs @@ -0,0 +1,19 @@ +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; +using Cnblogs.Architecture.IntegrationTestProject.Models; + +namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; + +public class ListArticlesQueryHandler : IPageableQueryHandler +{ + /// + public Task> Handle(ListArticlesQuery request, CancellationToken cancellationToken) + { + return Task.FromResult(new PagedList([new ArticleDto + { + Id = 1, + Title = "作为一个高中生开发者,我的所思所想" + } + ])); + } +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs index 0d8ad2b..f0f3365 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs @@ -1,6 +1,6 @@ -using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; using Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; -public record ListStringsQuery(PagingParams? PagingParams, string? OrderByString) : IPageableQuery; \ No newline at end of file +public record ListStringsQuery(PagingParams? PagingParams, string? OrderByString, string? culture) : IPageableQuery; diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQueryHandler.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQueryHandler.cs index 1d51ee7..04213d3 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQueryHandler.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQueryHandler.cs @@ -1,4 +1,4 @@ -using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; +using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; using Cnblogs.Architecture.Ddd.Infrastructure.Abstractions; namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; @@ -10,4 +10,4 @@ public Task> Handle(ListStringsQuery request, CancellationToke { return Task.FromResult(new PagedList(["hello"])); } -} \ No newline at end of file +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Models/ArticleDto.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Models/ArticleDto.cs new file mode 100644 index 0000000..50e48cd --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Models/ArticleDto.cs @@ -0,0 +1,7 @@ +namespace Cnblogs.Architecture.IntegrationTestProject.Models; + +public class ArticleDto +{ + public int Id { get; set; } + public string Title { get; set; } = string.Empty; +} diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs index fed4166..7523e41 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Program.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; using Cnblogs.Architecture.Ddd.EventBus.Abstractions; using Cnblogs.Architecture.Ddd.EventBus.Dapr; @@ -39,6 +39,7 @@ async (int stringId, [FromQuery] bool found = true) => await Task.FromResult(new GetStringQuery(StringId: stringId, Found: found))); v1.MapQuery("strings"); +v1.MapQuery("articles"); v1.MapQuery("long-to-string/{id:long}"); v1.MapCommand("long-to-string"); v1.MapCommand( diff --git a/test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs b/test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs new file mode 100644 index 0000000..c4e5a89 --- /dev/null +++ b/test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs @@ -0,0 +1,24 @@ +using Cnblogs.Architecture.IntegrationTestProject; +using Microsoft.AspNetCore.Mvc.Testing; + +namespace Cnblogs.Architecture.IntegrationTests; + +public class MinimalApiTests +{ + [Fact] + public async Task ResponseJsonWithChineseChars_RemainUnencodedAsync() + { + // Arrange + var builder = new WebApplicationFactory(); + + // Act + var response = await builder.CreateClient().GetAsync("/api/v1/articles"); + var content = await response.Content.ReadAsStringAsync(); + + Console.WriteLine(content); + + // Assert + Assert.True(response.IsSuccessStatusCode); + Assert.Contains("开发者", content); + } +} From b3de9bd87f254d08b745736f8709560f4c4f1810 Mon Sep 17 00:00:00 2001 From: dudu Date: Tue, 7 Oct 2025 21:49:05 +0800 Subject: [PATCH 2/2] refactor: reuse default SerializerOptions in Minimal APIs --- .../CqrsHttpOptions.cs | 3 ++- .../Application/Queries/ListStringsQuery.cs | 2 +- test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs index 71ea276..cc0ed1f 100644 --- a/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs +++ b/src/Cnblogs.Architecture.Ddd.Cqrs.AspNetCore/CqrsHttpOptions.cs @@ -1,6 +1,7 @@ using System.Text.Json; using Cnblogs.Architecture.Ddd.Cqrs.Abstractions; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Json; namespace Cnblogs.Architecture.Ddd.Cqrs.AspNetCore; @@ -25,5 +26,5 @@ public class CqrsHttpOptions /// /// For Controllers, please use builder.AddControllers().AddLongToStringJsonConverter(); /// - public JsonSerializerOptions DefaultJsonSerializerOptions { get; set; } = new(JsonSerializerDefaults.Web); + public JsonSerializerOptions DefaultJsonSerializerOptions { get; set; } = new JsonOptions().SerializerOptions; } diff --git a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs index f0f3365..d992b75 100644 --- a/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs +++ b/test/Cnblogs.Architecture.IntegrationTestProject/Application/Queries/ListStringsQuery.cs @@ -3,4 +3,4 @@ namespace Cnblogs.Architecture.IntegrationTestProject.Application.Queries; -public record ListStringsQuery(PagingParams? PagingParams, string? OrderByString, string? culture) : IPageableQuery; +public record ListStringsQuery(PagingParams? PagingParams, string? OrderByString) : IPageableQuery; diff --git a/test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs b/test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs index c4e5a89..c9f1a06 100644 --- a/test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs +++ b/test/Cnblogs.Architecture.IntegrationTests/MinimalApiTests.cs @@ -15,8 +15,6 @@ public async Task ResponseJsonWithChineseChars_RemainUnencodedAsync() var response = await builder.CreateClient().GetAsync("/api/v1/articles"); var content = await response.Content.ReadAsStringAsync(); - Console.WriteLine(content); - // Assert Assert.True(response.IsSuccessStatusCode); Assert.Contains("开发者", content);