Im trying to build a lambda expression and pass this into rulefor. The code compiles, but when executing I get the follwing message..
"'FluentValidation.Internal.RuleBuilder' does not contain a definition for 'Length'"
This is the validation code is this. The aim is that in two validators i want the same validation rule to be applied again username or a-another property.
public class UserValidator : AbstractValidator<DTO.User>
{
public UserValidator(DTO.User u)
{
foreach (PropertyInfo property in
this.GetType().BaseType
.GetGenericArguments()[0]
.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (property.Name == "Username")
{
ParameterExpression parameter = Expression.Parameter(typeof(DTO.User), "p");
Expression propertyAccess = Expression.Property(parameter, property);
// Make it easier to call RuleFor without knowing TProperty
dynamic lambda = Expression.Lambda(propertyAccess, parameter);
RuleFor(lambda)
.Length(4, 9)
.WithMessage("Valid between 4 and 9 chars");
//RuleFor(x => x.Username)
// .Length(4, 9)
// .WithMessage("Valid between 4 and 9 chars");
}
}
}
Any help appreciated...
I'm not sure if this is the kind of help you may be hoping for, but, what you're proposing is an unconventional use of the fluent framework. Your commented out code is the usual way to use this framework. This gives you the strong typing within the closed generic validator class (UserValidator) without the use of magic strings and reflection.
That said, if you really want to avoid the repetition of the code asserting the length then maybe you could do it using a helper which takes an expression as an argument:
public class User
{
public string Username { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
this.ValidateName(x => x.Username);
this.ValidateName(x => x.FirstName);
this.ValidateName(x => x.LastName);
}
}
public static class ValidationExtensions
{
public static void ValidateName<TV>(this AbstractValidator<TV> validator, Expression<Func<TV, string>> property)
{
validator.RuleFor(property).Length(4, 9).WithMessage("Valid between 4 and 9 chars");
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With