Add FluentValidation

This commit is contained in:
lumijiez
2025-06-10 00:23:11 +03:00
parent dd7eeb9eea
commit 10e3bedeea
18 changed files with 155 additions and 14 deletions

View File

@@ -1,6 +1,6 @@
using Imprink.Application.Products;
using Imprink.Application.Products.Dtos;
using Imprink.Domain.Common.Models;
using Imprink.Domain.Models;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

View File

@@ -1,6 +1,6 @@
using System.Security.Claims;
using Imprink.Application.Users;
using Imprink.Domain.Common.Models;
using Imprink.Domain.Models;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

View File

@@ -0,0 +1,41 @@
namespace Imprink.WebApi.Filters;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
public class ValidationActionFilter(IServiceProvider serviceProvider) : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
foreach (var parameter in context.ActionDescriptor.Parameters)
{
if (!context.ActionArguments.TryGetValue(parameter.Name, out var argument) || argument == null) continue;
var argumentType = argument.GetType();
var validatorType = typeof(IValidator<>).MakeGenericType(argumentType);
var validators = serviceProvider.GetServices(validatorType).Cast<IValidator>();
var validatorList = validators as IValidator[] ?? validators.ToArray();
if (validatorList.Length == 0) continue;
var validationContext = new ValidationContext<object>(argument);
var validationTasks = validatorList.Select(v => v.ValidateAsync(validationContext));
var validationResults = await Task.WhenAll(validationTasks);
var failures = validationResults
.SelectMany(r => r.Errors)
.Where(f => f != null)
.ToList();
if (failures.Count <= 0) continue;
var errors = failures.Select(e => new {
e.PropertyName, e.ErrorMessage
});
context.Result = new BadRequestObjectResult(new { Errors = errors });
return;
}
await next();
}
}

View File

@@ -8,6 +8,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentValidation" Version="12.0.0" />
<PackageReference Include="MediatR" Version="12.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.5" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />

View File

@@ -1,10 +1,13 @@
using System.Security.Claims;
using FluentValidation;
using Imprink.Application;
using Imprink.Application.Products.Create;
using Imprink.Application.Validation.Models;
using Imprink.Domain.Repositories;
using Imprink.Infrastructure;
using Imprink.Infrastructure.Database;
using Imprink.Infrastructure.Repositories;
using Imprink.WebApi.Filters;
using Imprink.WebApi.Middleware;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
@@ -37,11 +40,14 @@ public static class Startup
cfg.RegisterServicesFromAssembly(typeof(CreateProductHandler).Assembly);
});
services.AddValidatorsFromAssembly(typeof(Auth0UserValidator).Assembly);
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
})
.AddJwtBearer(options =>
{
options.Authority = builder.Configuration["Auth0:Authority"];
options.Audience = builder.Configuration["Auth0:Audience"];
@@ -78,7 +84,11 @@ public static class Startup
services.AddAuthorization();
services.AddControllers();
services.AddControllers(options =>
{
options.Filters.Add<ValidationActionFilter>();
});
services.AddSwaggerGen();
}