3

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...

1
  • 2
    Quick tip: Add the language that you are using in your list of tags (I've just done it). Your questions will have more chances to be read by experts in that language. I expect that most people filter questions by tags relevant to them. Commented Dec 19, 2012 at 8:10

1 Answer 1

3

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");
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.