fix(api): Исправлена ошибка асинхронной валидации FluentValidation
- удалён устаревший пакет FluentValidation.AspNetCore, вызывавший конфликт версий (NU1605) - реализован глобальный фильтр AsyncValidationFilter для поддержки MustAsync-правил
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
using FluentValidation;
|
||||
using FluentValidation.AspNetCore;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using PARR.API.Contracts.V1.Responses.Base;
|
||||
using PARR.API.Infrastructure.Filters;
|
||||
using PARR.API.Infrastructure.Middleware;
|
||||
|
||||
namespace PARR.API.Infrastructure
|
||||
@@ -22,7 +22,11 @@ namespace PARR.API.Infrastructure
|
||||
services.AddProblemDetails(); // Генерирует стандартный формат ошибки RFC 7807
|
||||
|
||||
// Настройка контроллеров и кастомного формата ошибок валидации
|
||||
services.AddControllers()
|
||||
services.AddControllers(options =>
|
||||
{
|
||||
// Автоматически применяем асинхронную валидацию ко всем контроллерам
|
||||
options.Filters.Add<AsyncValidationFilter>();
|
||||
})
|
||||
.ConfigureApiBehaviorOptions(options =>
|
||||
{
|
||||
options.InvalidModelStateResponseFactory = context =>
|
||||
@@ -43,7 +47,10 @@ namespace PARR.API.Infrastructure
|
||||
//services.AddValidatorsFromAssemblies(Assembly.GetExecutingAssembly());
|
||||
|
||||
// Включаем авто-валидацию FluentValidation для контроллеров
|
||||
services.AddFluentValidationAutoValidation();
|
||||
//services.AddFluentValidationAutoValidation();
|
||||
|
||||
services.AddScoped<AsyncValidationFilter>();
|
||||
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
47
PARR.API/Infrastructure/Filters/AsyncValidationFilter.cs
Normal file
47
PARR.API/Infrastructure/Filters/AsyncValidationFilter.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using FluentValidation;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using PARR.API.Contracts.V1.Responses.Base;
|
||||
|
||||
namespace PARR.API.Infrastructure.Filters
|
||||
{
|
||||
public class AsyncValidationFilter : IAsyncActionFilter
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public AsyncValidationFilter(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
foreach (var argument in context.ActionArguments.Values)
|
||||
{
|
||||
if (argument == null)
|
||||
continue;
|
||||
|
||||
var validatorType = typeof(IValidator<>).MakeGenericType(argument.GetType());
|
||||
var validator = _serviceProvider.GetService(validatorType);
|
||||
|
||||
if (validator is IValidator validatorInstance)
|
||||
{
|
||||
var validationContext = new ValidationContext<object>(argument);
|
||||
var validationResult = await validatorInstance.ValidateAsync(validationContext, context.HttpContext.RequestAborted);
|
||||
|
||||
if (!validationResult.IsValid)
|
||||
{
|
||||
var errors = validationResult.Errors
|
||||
.Select(e => new ErrorModel { Message = e.ErrorMessage })
|
||||
.ToList();
|
||||
|
||||
context.Result = new BadRequestObjectResult(new Response(false, errors));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +1,44 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1701;1702;1591;1587;1573;NU1803</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1701;1702;1591;1587;1573;NU1803</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<NoWarn>1701;1702;1591;1587;1573;NU1803</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<NoWarn>1701;1702;1591;1587;1573;NU1803</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="8.19.0" />
|
||||
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.1" />
|
||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.16" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.16">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.6" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="12.0.1" />
|
||||
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="8.19.0" />
|
||||
<PackageReference Include="FluentValidation" Version="12.1.1" />
|
||||
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.16" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.16">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.23.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Hosting" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PARR.Core\PARR.Core.csproj" />
|
||||
<ProjectReference Include="..\PARR.DAL\PARR.DAL.csproj" />
|
||||
<ProjectReference Include="..\PARR.Infrastructure\PARR.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\PARR.Core\PARR.Core.csproj" />
|
||||
<ProjectReference Include="..\PARR.DAL\PARR.DAL.csproj" />
|
||||
<ProjectReference Include="..\PARR.Infrastructure\PARR.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace PARR.API.Validators
|
||||
{
|
||||
private readonly ITnkRepository tnkService;
|
||||
private readonly IJobGroupRepository jobGroupService;
|
||||
private readonly IJobRepository jobService;
|
||||
private readonly IJobRepository jobRepository;
|
||||
private readonly IUnitFieldRepository unitFieldService;
|
||||
private JobGroup? jobGroup;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace PARR.API.Validators
|
||||
{
|
||||
this.tnkService = tnkService;
|
||||
this.jobGroupService = jobGroupService;
|
||||
this.jobService = jobService;
|
||||
this.jobRepository = jobService;
|
||||
this.unitFieldService = unitFieldService;
|
||||
|
||||
RuleFor(t => t.Name)
|
||||
|
||||
Reference in New Issue
Block a user