Last active
September 4, 2024 08:09
-
-
Save marcominerva/1cd303f99478efad3f1cbdee511b2b02 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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