Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation of a field with ValidationContext returns errors for unexpected fields #1989

Closed
vladidem opened this issue Aug 8, 2022 · 2 comments
Milestone

Comments

@vladidem
Copy link

vladidem commented Aug 8, 2022

FluentValidation version

11.1.1

ASP.NET version

6.0

Summary

There is a hierarchy of classes. They use validators with Include to include base class validator.
I'm trying to validate only one field by using ValidationContext with MemberNameValidatorSelector.
For base class it works as expected, for inheritor validation returns errors for different fields, not included in MemberNameValidatorSelector.

Steps to Reproduce

You can try out a demo on dotnetfiddle.

A hierarchy of classes :

public class Foo
{
    public string FooString { get; set; }   
    public List<string> FooList { get; set; } = new();
}

public class Bar : Foo
{
}

public class Baz : Bar
{
}

Validators:

public class FooValidator : AbstractValidator<Foo>
{
    public FooValidator()
    {
        RuleFor((it) => it.FooString).NotEmpty();
    }
}

public class BarValidator : AbstractValidator<Bar>
{
    public BarValidator()
    {
        Include(new FooValidator());
	RuleFor((it) => it.FooList).NotEmpty();
    }
}

public class BazValidator : AbstractValidator<Baz>
{
    public BazValidator()
    {
        Include(new BarValidator());
    }
}

When calling validation for FooString property of Bar:

Bar bar = new Bar() { FooString = "NotEmpty" };
var properties = new[] { nameof(Bar.FooString) };
var context = new ValidationContext<Bar>(bar, new PropertyChain(), new MemberNameValidatorSelector(properties));
IValidator v = new BarValidator();
var result = v.Validate(context); // result.Errors is empty

result has no errors as expected.

But with the same code for FooString property of Baz:

Baz baz = new Baz() { FooString = "NotEmpty" };
var properties = new[] { nameof(Baz.FooString) };
var context = new ValidationContext<Baz>(baz, new PropertyChain(), new MemberNameValidatorSelector(properties));
IValidator v = new BazValidator();
var result = v.Validate(context); // result.Errors has an error for FooList

result has an error for FooList, even thought it is not included in properties.

@JeremySkinner
Copy link
Member

JeremySkinner commented Aug 8, 2022

Thanks for reporting this. I've started investigating it and It looks like there's something strange going on with the ordering of the rules.

If you swap around the order of the Include and the other rule it works correctly:

// Doesn't work
public BarValidator()
{
  Include(new FooValidator());
  RuleFor((it) => it.FooList).NotEmpty();
}

// Works
public BarValidator()
{
  RuleFor((it) => it.FooList).NotEmpty();
  Include(new FooValidator());
}

I've run out of time to look at this further, but I'll try and pick it up again later.

JeremySkinner added a commit that referenced this issue Aug 8, 2022
@JeremySkinner
Copy link
Member

This is happening because of the nested calls to Include. The state key that tracks whether an Include rule should be considered by the MemberNameValidatorSelector was being cleared too early. Fixed in 41ca856

I've pushed out the 11.2.0 release to Nuget which includes this fix.

@JeremySkinner JeremySkinner added this to the 11.2.0 milestone Aug 8, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants