Skip to content

Instantly share code, notes, and snippets.

@marcominerva
Last active September 4, 2024 08:14
Show Gist options
  • Save marcominerva/9d43680d8436db23c63d1ba632637f8d to your computer and use it in GitHub Desktop.
Save marcominerva/9d43680d8436db23c63d1ba632637f8d to your computer and use it in GitHub Desktop.
using System.Diagnostics;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
namespace MinimalApi.Filters;
public class ValidatorFilter<T>(IValidator<T> validator) : IEndpointFilter where T : class
{
public async ValueTask<object?> InvokeAsync(EndpointFilterInvocationContext context, EndpointFilterDelegate next)
{
if (context.Arguments.FirstOrDefault(a => a?.GetType() == typeof(T)) is not T input)
{
return TypedResults.BadRequest();
}
var validationResult = await validator.ValidateAsync(input);
if (validationResult.IsValid)
{
return await next(context);
}
var statusCode = StatusCodes.Status400BadRequest;
var problemDetails = new ProblemDetails
{
Status = statusCode,
Type = $"https://httpstatuses.io/{statusCode}",
Title = "One or more validation errors occurred",
Instance = context.HttpContext.Request.Path
};
problemDetails.Extensions["traceId"] = Activity.Current?.Id ?? context.HttpContext.TraceIdentifier;
problemDetails.Extensions["errors"] = validationResult.ToDictionary();
return TypedResults.Json(problemDetails, statusCode: StatusCodes.Status400BadRequest, contentType: "application/problem+json; charset=utf-8");
}
}
public static class RouteHandlerBuilderExtensions
{
public static RouteHandlerBuilder WithValidation<T>(this RouteHandlerBuilder builder) where T : class
=> builder.AddEndpointFilter<ValidatorFilter<T>>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment