Skip to content

Min API validation throws when IValidatableObject returns ValidationResult without MemberNames #61739

Closed
@sbomer

Description

@sbomer

Repro:

using Microsoft.AspNetCore.Http.Validation;
using Microsoft.Extensions.Options;
using System.ComponentModel.DataAnnotations;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddValidation();
var app = builder.Build();

var model = new Model { Name = "Name" };

var validationOptions = app.Services.GetService<IOptions<ValidationOptions>>()!.Value;
if (!validationOptions.TryGetValidatableTypeInfo(typeof(Model), out var typeInfo))
{
    throw new InvalidOperationException("Type not found in validation options.");
}
var validateContext = new ValidateContext()
{
    ValidationOptions = validationOptions,
    ValidationContext = new ValidationContext(model)
};
typeInfo.ValidateAsync(model, validateContext, CancellationToken.None).GetAwaiter().GetResult();

[ValidatableType]
class Model : IValidatableObject
{
    [Required]
    public required string Name { get; init; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Name != "MyName")
        {
            yield return new ValidationResult("Name must be MyName");
            // yield return new ValidationResult("Name must be MyName", new[] { nameof(Name) }); // This would fix it
        }
    }
}

This throws an exception:

Unhandled exception. System.InvalidOperationException: Sequence contains no elements
   at System.Linq.ThrowHelper.ThrowNoElementsException()
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at Microsoft.AspNetCore.Http.Validation.ValidatableTypeInfo.ValidateAsync(Object value, ValidateContext context, CancellationToken cancellationToken)
   at Program.<Main>$(String[] args) in /home/svbomer/src/test-apps/validationGen/Program.cs:line 21

Setting MemberNames on the ValidationResult fixes this. Is it by design? Should there be a better error message when this happens? It's a minor pain point when migrating existing IValidatableObject implementations that don't set MemberNames

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-validationIssues related to model validation in minimal and controller-based APIs

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions