Skip to content

Instantly share code, notes, and snippets.

@marcominerva
Last active September 4, 2024 08:09
Show Gist options
  • Save marcominerva/1cd303f99478efad3f1cbdee511b2b02 to your computer and use it in GitHub Desktop.
Save marcominerva/1cd303f99478efad3f1cbdee511b2b02 to your computer and use it in GitHub Desktop.
using System.Diagnostics;
using FluentValidation;
using Microsoft.AspNetCore.Mvc;
using OperationResults.AspNetCore.Http;
namespace MinimalApi.Filters;
public class ValidatorFilter<T>(IValidator<T> validator, OperationResultOptions options) : 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 = Messages.ValidationErrors,
Instance = context.HttpContext.Request.Path
};
problemDetails.Extensions["traceId"] = Activity.Current?.Id ?? context.HttpContext.TraceIdentifier;
if (options.ErrorResponseFormat == ErrorResponseFormat.Default)
{
problemDetails.Extensions["errors"] = validationResult.ToDictionary();
}
else
{
var errors = validationResult.Errors.Select(e => new { Name = e.PropertyName, Message = e.ErrorMessage });
problemDetails.Extensions["errors"] = errors;
}
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