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

Add a PropertyPath placeholder #2134

Closed
JeremySkinner opened this issue Aug 6, 2023 · 4 comments · Fixed by #2135
Closed

Add a PropertyPath placeholder #2134

JeremySkinner opened this issue Aug 6, 2023 · 4 comments · Fixed by #2135
Milestone

Comments

@JeremySkinner
Copy link
Member

JeremySkinner commented Aug 6, 2023

Is your feature request related to a problem? Please describe.

Allow access to the full property path inside error message templates.

Describe the solution you'd like

  • Deprecate ValidationContext.PropertyName
  • Add ValidationContext.PropertyPath as a better-named replacement
  • Add this as a message placeholder within RuleBase.PrepareMessageFormatterForValidationError

Describe alternatives you've considered

No response

Additional Context

No response

@rez-gparker
Copy link

Thank you for adding this. I think it will be a nice addition.

I cannot reply to #2132 because it is locked, but I just wanted to say this is an awesome library and I doubt there is a better one out there. So, forgive my poor choice of words when I said that having to add WithFullName to every rule stinks in previous post.

Also, are you sure adding PropertyPath to ValidatorOptions.Global.DisplayNameResolver would be difficult? It looks like the full property path (variable propertyName) is set a couple of lines below the call to GetDisplayName here. Could it not be set earlier and passed into GetDisplayName?

string displayName = GetDisplayName(context);

if (PropertyName == null && displayName == null) {
	//No name has been specified. Assume this is a model-level rule, so we should use empty string instead.
	displayName = string.Empty;
}

// Construct the full name of the property, taking into account overriden property names and the chain (if we're in a nested validator)
string propertyName = context.PropertyChain.BuildPropertyName(PropertyName ?? displayName);

@JeremySkinner
Copy link
Member Author

Also, are you sure adding PropertyPath to ValidatorOptions.Global.DisplayNameResolver would be difficult?

I am certain. As I explained in the other thread, the DisplayNameResolver needs to support being executed without a property path, which is why it's not passed in. There are several scenarios where this happens but the most common is for our integration with ASP.NET's client-side validation. We need to generate messages without invoking the validator. There is no validation context available in that scenario, no property path, no model being validated.

As an example, see https://github.com/FluentValidation/FluentValidation.AspNetCore/blob/3ab2baedddded12ed6727d598f7355264bcca31c/src/FluentValidation.AspNetCore/Adapters/CreditCardClientValidator.cs#L33

The property name is being generated completely outside of a validation run - it can't rely on things that are only available during validation. So adding the property path as a parameter to DisplayNameResolver is not something that can happen.

@rez-gparker
Copy link

I see now. Thank you for the explanation.

@JeremySkinner
Copy link
Member Author

11.7.0 is now released with this change

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 26, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants