Closed
Description
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