You can use middleware for this:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers().ConfigureApiBehaviorOptions(options =>
{
    options.InvalidModelStateResponseFactory = context =>
    {
        var result = new ValidationFailedResult(context.ModelState);
        result.ContentTypes.Add(MediaTypeNames.Application.Json);
        return result;
    };
});
and ValidationFailedResult:
public class ValidationFailedResult : ObjectResult
    {
        public ValidationFailedResult(ModelStateDictionary modelState)
            : base(new ErrorResponse(modelState.Keys
                     .SelectMany(key => modelState[key].Errors.Select(x => new ApplicationError(StatusCodes.Status422UnprocessableEntity, key, x.ErrorMessage)))
                     .ToList()))
        {
            StatusCode = StatusCodes.Status422UnprocessableEntity; //change the http status code to 422.
        }
    }
and ApplicationError:
 public class ApplicationError
    {
        public ApplicationError(int code, string title, string detail)
        {
            Code=code;
            Title=title;
            Detail=detail;
        }
        public int Code { get; set; }
        public string Title { get; set; }
        public string Detail { get; set; }
        public override string ToString()
        {
            return $"Status:{Code} Title:{Title} Detail:{Detail}";
        }
    }
The result looks like this:
{
    "errors": [
        {
            "code": 422,
            "title": "$",
            "detail": "'\"' is invalid after a value. Expected either ',', '}', or ']'. Path: $ | LineNumber: 7 | BytePositionInLine: 1."
        },
        {
            "code": 422,
            "title": "input",
            "detail": "The input field is required."
        }
    ]
}
Source:
https://learn.microsoft.com/en-us/answers/questions/620570/net-core-web-api-model-validation-error-response-t.html