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

Validating primitive types #184

Closed
DixonDs opened this issue Dec 26, 2015 · 7 comments
Closed

Validating primitive types #184

DixonDs opened this issue Dec 26, 2015 · 7 comments

Comments

@DixonDs
Copy link
Contributor

DixonDs commented Dec 26, 2015

I'm trying to find a way how I can use built-in validators to validate primitive types like strings or ints. For example, I would like to be able to use EmailValidator to validate a string value (not a string property of a complex type) by calling something like Validate. But EmailValidator is IPropertyValidator, not IValidator.

Any ideas how to use FluentValidation to validate primitive types?

@JeremySkinner
Copy link
Member

That isn't really something that's supported I'm afraid. The whole point of FluentValidation is to validate properties on objects.

Technically, you can define rules for primitives like this:

public class MyValidator: AbstractValidator<string> {
  public MyValidator() {
     RuleFor(x=>x).EmailAddress();
  }
}

...however, you will find that there are some features that don't work with this approach, and isn't really recommended.

@aschaible
Copy link

Similar to this, is there a way to define a set of rules for a primitive type, and reuse that set of rules? For example, if I want to validate the complexity of a password with several checks, but I have multiple models that use those same checks - I would rather not refactor the password component into a complex type. It would be great to group multiple rules into a group and be able to reuse them.

I did see rule sets, but those are a bit different.

Thanks!

@JeremySkinner
Copy link
Member

Yes, you have a couple of options. You can use the approach I documented above, by creating an AbstractValidator instance that acts on strings. The other option is to write an extension that wraps the multiple calls to RuleFor.

@aschaible
Copy link

Hi Jeremy,

Thanks for the quick response! I've been looking for examples of the second approach, wrapping multiple calls to RuleFor and have not found any. Do you have any advice there?

@JeremySkinner
Copy link
Member

Sure, here's an example that chains multiple rules on a string property, within an extension method.

// In the validator
RuleFor(x => x.Surname).CustomSurnameValidation();
// Custom extensions class
public static class MyExtensions {

  // Generic type is hard-coded to string, menaing this method will only appear for string properties.
  // If you wanted it to appear for *all* properties, introduce a second type-parameter called TProperty
  public static IRuleBuilderOptions<T, string> CustomSurnameValidation<T>(this IRuleBuilder<T, string> rule) {
    return rule.NotNull().NotEqual("foo");
  } 
}

This is actually how all of FV's default validation rules (NotNull, NotEmpty etc) work- they're all extesnions on IRuleBuilder that perform certain actions (usually calling SetValidator to encapsulate within a custom property validator)

@aschaible
Copy link

Thanks Jeremy!

@SeanKilleen
Copy link
Contributor

Maintenance / cleanup: Closing this as the question appears to be answered.

@lock lock bot locked and limited conversation to collaborators Aug 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants