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

@@ -8,8 +8,10 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="FluentValidation" Version="12.0.0-preview1" />
<PackageReference Include="FluentValidation" Version="12.0.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="12.0.0" />
<PackageReference Include="MediatR" Version="12.5.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.4" />
</ItemGroup>
@@ -17,4 +19,8 @@
<ProjectReference Include="..\Imprink.Domain\Imprink.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Validation\Users\" />
</ItemGroup>
</Project>

View File

@@ -1,5 +1,5 @@
using Imprink.Application.Products.Dtos;
using Imprink.Domain.Common.Models;
using Imprink.Domain.Models;
using MediatR;
namespace Imprink.Application.Products;

View File

@@ -1,4 +1,4 @@
using Imprink.Domain.Common.Models;
using Imprink.Domain.Models;
using MediatR;
namespace Imprink.Application.Users;

View File

@@ -0,0 +1,23 @@
using FluentValidation;
using Imprink.Domain.Models;
namespace Imprink.Application.Validation.Models;
public class Auth0UserValidator : AbstractValidator<Auth0User>
{
public Auth0UserValidator()
{
RuleFor(x => x.Sub)
.NotEmpty();
RuleFor(x => x.Name)
.NotEmpty();
RuleFor(x => x.Nickname)
.NotEmpty();
RuleFor(x => x.Email)
.NotEmpty()
.EmailAddress();
}
}

View File

@@ -0,0 +1,45 @@
using FluentValidation;
using Imprink.Domain.Models;
namespace Imprink.Application.Validation.Models;
public class ProductFilterParametersValidator : AbstractValidator<ProductFilterParameters>
{
public ProductFilterParametersValidator()
{
RuleFor(x => x.PageNumber)
.GreaterThan(0).WithMessage("PageNumber must be greater than 0.");
RuleFor(x => x.PageSize)
.InclusiveBetween(1, 100).WithMessage("PageSize must be between 1 and 100.");
RuleFor(x => x.SearchTerm)
.Length(1, 100).WithMessage("Length must be between 1 and 100.")
.When(x => !string.IsNullOrWhiteSpace(x.SearchTerm));
RuleFor(x => x.MinPrice)
.GreaterThanOrEqualTo(0).When(x => x.MinPrice.HasValue)
.WithMessage("MinPrice cannot be negative.");
RuleFor(x => x.MaxPrice)
.GreaterThanOrEqualTo(0).When(x => x.MaxPrice.HasValue)
.WithMessage("MaxPrice cannot be negative.");
RuleFor(x => x)
.Must(x => !x.MinPrice.HasValue || !x.MaxPrice.HasValue || x.MinPrice <= x.MaxPrice)
.WithMessage("MinPrice cannot be greater than MaxPrice.");
RuleFor(x => x.SortBy)
.NotEmpty().WithMessage("SortBy is required.")
.Must(value => AllowedSortColumns.Contains(value, StringComparer.OrdinalIgnoreCase))
.WithMessage("SortBy must be one of: Name, Price, CreatedDate.");
RuleFor(x => x.SortDirection)
.NotEmpty().WithMessage("SortDirection is required.")
.Must(value => value.Equals("ASC", StringComparison.OrdinalIgnoreCase)
|| value.Equals("DESC", StringComparison.OrdinalIgnoreCase))
.WithMessage("SortDirection must be 'ASC' or 'DESC'.");
}
private static readonly string[] AllowedSortColumns = ["Name", "Price", "CreatedDate"];
}

View File

@@ -0,0 +1,15 @@
using FluentValidation;
using Imprink.Application.Products;
using Imprink.Application.Validation.Models;
namespace Imprink.Application.Validation.Products;
public class GetProductsQueryValidator : AbstractValidator<GetProductsQuery>
{
public GetProductsQueryValidator()
{
RuleFor(x => x.FilterParameters)
.NotNull()
.SetValidator(new ProductFilterParametersValidator());
}
}