Skip to content

Commit

Permalink
Merge pull request #88 from coder-1jie/dev
Browse files Browse the repository at this point in the history
Adjust KnownExceptionValidationBehavior 使用 ValidateAsync 以支持异步验证器
  • Loading branch information
witskeeper authored Oct 28, 2024
2 parents f9b638a + e842b62 commit d61bb54
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 13 deletions.
7 changes: 4 additions & 3 deletions src/AspNetCore/Validation/KnownExceptionValidationBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,17 @@ public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TRe
}

var context = new ValidationContext<TRequest>(request);
var errorsDictionary = _validators
.Select(x => x.Validate(context))
var errorsDictionary = (await Task.WhenAll(
_validators.Select(x => x.ValidateAsync(context, cancellationToken)))
)
.SelectMany(x => x.Errors)
.Where(x => x != null).ToList();
if (errorsDictionary.Any())
{
throw new KnownException(message: errorsDictionary[0].ErrorMessage, errorCode: 400,
errorData: errorsDictionary.Select(p =>
new { errorCode = p.ErrorCode, errorMessage = p.ErrorMessage, propertyName = p.PropertyName }
).ToArray());
).ToArray<object>());
}

return await next();
Expand Down
26 changes: 23 additions & 3 deletions test/NetCorePal.Web.UnitTests/ProgramTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using NetCorePal.SkyApm.Diagnostics;
using NetCorePal.Web.Application.IntegrationEventHandlers;
using NetCorePal.Web.Application.Queries;
using NetCorePal.Web.Controllers.Request;

namespace NetCorePal.Web.UnitTests
{
Expand Down Expand Up @@ -122,7 +123,7 @@ public async Task ServiceUnknownExceptionTest()
public async Task PostTest()
{
var client = factory.CreateClient();
var response = await client.PostAsJsonAsync("/api/order", new CreateOrderCommand("na", 55, 14), JsonOption);
var response = await client.PostAsJsonAsync("/api/order", new CreateOrderRequest("na", 55, 14), JsonOption);
Assert.True(response.IsSuccessStatusCode);
var data = await response.Content.ReadFromJsonAsync<OrderId>(JsonOption);
Assert.NotNull(data);
Expand All @@ -145,7 +146,7 @@ public async Task PostTest()
public async Task SetPaidTest()
{
var client = factory.CreateClient();
var response = await client.PostAsJsonAsync("/api/order", new CreateOrderCommand("na", 55, 14), JsonOption);
var response = await client.PostAsJsonAsync("/api/order", new CreateOrderRequest("na", 55, 14), JsonOption);
Assert.True(response.IsSuccessStatusCode);
var data = await response.Content.ReadFromJsonAsync<OrderId>(JsonOption);
Assert.NotNull(data);
Expand Down Expand Up @@ -181,7 +182,7 @@ public async Task SetPaidTest()
public async Task SetOrderItemNameTest()
{
var client = factory.CreateClient();
var response = await client.PostAsJsonAsync("/api/order", new CreateOrderCommand("na", 55, 14), JsonOption);
var response = await client.PostAsJsonAsync("/api/order", new CreateOrderRequest("na", 55, 14), JsonOption);
Assert.True(response.IsSuccessStatusCode);
var data = await response.Content.ReadFromJsonAsync<OrderId>(JsonOption);
Assert.NotNull(data);
Expand Down Expand Up @@ -216,5 +217,24 @@ public async Task Int64StronglyTypedId_FromRoute_Should_Work_Test()
Assert.True(data.Success);
Assert.Equal(id, data.Data.Id);
}

[Fact]
public async Task CreateOrderValidator_Should_ValidateWithAsync_WhenPosting()
{
var client = factory.CreateClient();
var response = await client.PostAsJsonAsync("/api/order", new CreateOrderRequest("na", 55, 14), JsonOption);
Assert.True(response.IsSuccessStatusCode);
var data = await response.Content.ReadFromJsonAsync<OrderId>(JsonOption);
Assert.NotNull(data);


response = await client.PostAsJsonAsync("/api/order", new CreateOrderRequest("na", 55, -1), JsonOption);
Assert.True(response.IsSuccessStatusCode);
var errData = await response.Content.ReadFromJsonAsync<ResponseData>();
Assert.NotNull(errData);
Assert.Contains("Count", errData.Message);
Assert.Equal(400, errData.Code);
Assert.False(errData.Success);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public CreateOrderCommandValidator()
{
RuleFor(x => x.Name).NotEmpty().MaximumLength(10);
RuleFor(x => x.Price).InclusiveBetween(18, 60);
RuleFor(x => x.Count).MustAsync(async (c, ct) => {
await Task.CompletedTask;
return c > 0;
} );
}
}
}
11 changes: 6 additions & 5 deletions test/NetCorePal.Web/Controllers/OrderController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using NetCorePal.Web.Application.IntegrationEventHandlers;
using NetCorePal.Web.Application.Queries;
using NetCorePal.Web.Application.Sagas;
using NetCorePal.Web.Controllers.Request;
using SkyApm.Tracing;

namespace NetCorePal.Web.Controllers
Expand Down Expand Up @@ -40,12 +41,12 @@ public IActionResult Get()
/// <summary>
///
/// </summary>
/// <param name="command"></param>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost]
public async Task<OrderId> Post([FromBody] CreateOrderCommand command)
public async Task<OrderId> Post([FromBody] CreateOrderRequest request)
{
var id = await mediator.Send(command, HttpContext.RequestAborted);
var id = await mediator.Send(new CreateOrderCommand(request.Name, request.Price, request.Count), HttpContext.RequestAborted);
return id;
}

Expand Down Expand Up @@ -75,7 +76,7 @@ public async Task<ResponseData> SetPaid(OrderId id)
await mediator.Send(new OrderPaidCommand(id), HttpContext.RequestAborted);
return true.AsResponseData();
}

/// <summary>
///
/// </summary>
Expand All @@ -84,7 +85,7 @@ public async Task<ResponseData> SetPaid(OrderId id)
/// <returns></returns>
[HttpPost]
[Route("/setorderItemName")]
public async Task<ResponseData> SetOrderItemName([FromQuery]long id, [FromQuery]string name)
public async Task<ResponseData> SetOrderItemName([FromQuery] long id, [FromQuery] string name)
{
await mediator.Send(new SetOrderItemNameCommand(new OrderId(id), name), HttpContext.RequestAborted);
return true.AsResponseData();
Expand Down
4 changes: 4 additions & 0 deletions test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace NetCorePal.Web.Controllers.Request
{
public record CreateOrderRequest(string Name, int Price, int Count);

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.CreateOrderRequest(string, int, int)'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.Name'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.Price'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.Count'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.CreateOrderRequest(string, int, int)'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.Name'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.Price'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest.Count'

Check warning on line 3 in test/NetCorePal.Web/Controllers/Request/CreateOrderRequest.cs

View workflow job for this annotation

GitHub Actions / build

Missing XML comment for publicly visible type or member 'CreateOrderRequest'
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await using (handler)
{
var command = new CreateOrderCommand("abc", 10, 20);
var command = new CreateOrderCommand("abc", 20, 20);
await mediator.Send(command, stoppingToken);
await Task.Delay(100, stoppingToken);
}
Expand Down
3 changes: 2 additions & 1 deletion test/NetCorePal.Web/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@

builder.Services.AddContext().AddEnvContext().AddCapContextProcessor();
builder.Services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly()).AddUnitOfWorkBehaviors());
cfg.RegisterServicesFromAssemblies(Assembly.GetExecutingAssembly()).AddUnitOfWorkBehaviors()
.AddKnownExceptionValidationBehavior());
builder.Services.AddRepositories(typeof(ApplicationDbContext).Assembly);
builder.Services.AddDbContext<ApplicationDbContext>(options =>
{
Expand Down

0 comments on commit d61bb54

Please sign in to comment.