ValidationFilter.cs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. using FluentValidation;
  2. namespace WebTemplate.ServerAspects.Validation;
  3. /// <summary>
  4. /// Since the FluentValidation.AspNetCore package is no longer supported and the documentation under
  5. /// https://docs.fluentvalidation.net/en/latest/aspnet.html?highlight=asp.net%20core#using-a-filter suggests using
  6. /// a custom filter, this is what we are doing.
  7. ///
  8. /// The code is heavily inspired by a "coding short" video by Shawn Wildermuth but customized a bit.
  9. /// https://www.youtube.com/watch?v=_S-r6SxLGn4
  10. /// </summary>
  11. /// <typeparam name="T">The object type that should be validated.</typeparam>
  12. public class ValidationFilter<T> : IEndpointFilter
  13. {
  14. public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext ctx, EndpointFilterDelegate next)
  15. {
  16. var validator = ctx.HttpContext.RequestServices.GetService<IValidator<T>>();
  17. if (validator is null)
  18. {
  19. return Results.Problem($"No validator found for type {typeof(T).Name}");
  20. }
  21. var entity = ctx.Arguments
  22. .OfType<T>()
  23. .FirstOrDefault(a => a?.GetType() == typeof(T));
  24. if (entity is not null)
  25. {
  26. var validation = await validator.ValidateAsync(entity);
  27. if (validation.IsValid)
  28. {
  29. return await next(ctx);
  30. }
  31. return Results.ValidationProblem(validation.ToDictionary());
  32. }
  33. return Results.Problem("Could not find type to validate");
  34. }
  35. }