question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Could not infer property name using generic list with the newest FluentValidation version.

See original GitHub issue

Hi,

I just upgrade our fluent validation version to be able to use new features (which are awesome). However, I’m facing an issue with existing validations we have in our system.

We are not using a conventional model in our current framework. We have a global class Entity that defines an entity and the global property. This class contains a list of children List<Entity> which can contains multiple type of entities. Because of this, we had to hack the way fluentValidation works and use the OfType on our global list to pass the right details to our validator. I wrote a sample of code below to demonstrate how we did it.

This was previously working and is not working anymore. The error that we have now is the following one:

Could not infer property name for expression: p => new <>f__AnonymousType0`1(F2s = p.Foos.OfType()).F2s. Please explicitly specify a property name by calling OverridePropertyName as part of the rule chain.

// Abstract Parent
public abstract class MasterFoo
{
    public IEnumerable<MasterFoo> Foos {get;set;}
}

// Parent Class
public class F1 : MasterFoo
{
    public IEnumerable<F2> F2s => Details.OfType<F2>();
}

// Child Class
public class F2 : MasterFoo{...}
public class F3 : MasterFoo{...}

// Parent that contains 2 type of childs.
F1 parent = new F1();
F2 child1 = new F2();
F3 child2 = new F3();

parent.AddChild(child1)
parent.AddChild(child2)

// Parent validator
public class F1Validator : AbstractValidator<F1>
{
    public F1Validator
    {
        // Does work
        RuleFor(p => p.F2s).SetCollectionValidator(new F2Validator());

        // Does not work (Inferring issue)
        RuleFor(p => new { F2s = p.Foos.OfType<F2>() }.F2s).SetCollectionValidator(new F2Validator());

        // Does not work (Inferring issue)
        RuleFor(p => p.Foos.OfType<F2>()).SetCollectionValidator(new F2Validator());
    }
}

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
JeremySkinnercommented, Jan 30, 2018

Actually I just tried this and it seems to work OK. You can set something like this in your application’s startup routine:

FluentValidation.ValidatorOptions.PropertyNameResolver = (type, member, expression) => {
  string propertyName = null;
  
  if (expression != null) {
    var chain = PropertyChain.FromExpression(expression);
    if (chain.Count > 0) propertyName = chain.ToString();
  }
  else {
   propertyName = memberInfo?.Name;
  }
  
  if(string.IsNullOrEmpty(propertyName)) {
    return "Undefined";
  }
  
  return propertyName;

};
1reaction
JeremySkinnercommented, Dec 20, 2017

Hi,

This is the expected behaviour. By default, a call to RuleFor expects a lambda expression that defines a simple property accessor. If you’re doing anything more complex inside a call to RuleFor (including anything that performs method calls to OfType, or any other method call), then FluentValidation won’t automatically infer the property name, so you need to tell it yourself the name of the property with which the expression is associated. The error message does actually explain how to do this pretty clearly:

Could not infer property name for expression: p => new <>f__AnonymousType0`1(F2s = p.Foos.OfType()).F2s. Please explicitly specify a property name by calling OverridePropertyName as part of the rule chain.

So just do as it suggests and add a call to OverridePropertyName:

RuleFor(p => p.Foos.OfType<F2>())
  .SetCollectionValidator(new F2Validator());
  .OverridePropertyName("F2s"); //or Foos or whetever you want to call it

This may not have been necessary in some older version of FluentValidation, but since expression caching was introduced in 7.x (for performance reasons) this is a requirement if you are not using simple property accessors.

Hope that helps

Read more comments on GitHub >

github_iconTop Results From Across the Web

Could not infer property name using generic list with the ...
Hi, I just upgrade our fluent validation version to be able to use new features (which are awesome). However, I'm facing an issue...
Read more >
fluentvalidation error message contains c# property name ...
I have a C# WebApi project and i am using FluentValidation.WebApi package for validation of client inputs. Below is my model class code...
Read more >
Custom Validators — FluentValidation documentation
The simplest way to implement a custom validator is by using the Must method ... To ensure our list property contains fewer than...
Read more >
10.0 Upgrade Guide — FluentValidation documentation
Custom property validators are now generic, and inherit from either PropertyValidator<T ... The non-generic version will be removed in FluentValidation 11.
Read more >
Overriding the Message — FluentValidation documentation
Each built-in validator has its own list of placeholders. The placeholders used in all validators are: {PropertyName} – Name of the property being...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found