public IEnumerable <RuleDescription> GetNestedRules(string propertyName, PropertyRule rule, ChildValidatorAdaptor childValidator, IRuleBuilder ruleBuilder)
        {
            //HACK: I hate this explicit defintion.
            var          coreDocumentationType = typeof(DocBuilder);
            const string methodIdentifier      = "Document";

            var getRulesMethodDefinition = coreDocumentationType.ExtractMethodInfo(new[] { methodIdentifier })[methodIdentifier];

            // Create the generic method instance of Document()
            getRulesMethodDefinition = getRulesMethodDefinition.MakeGenericMethod(childValidator.ValidatorType.GetTypeInfo().BaseType.GenericTypeArguments[0]);

            //Parameter 1 = Validator instance derived from AbstractValidator<T>, Parameter 2 = boolean (documentNested)
            var parameterArray = new object[]
            {
                childValidator.GetValidator(_fluentValidationHelper.BuildPropertyValidatorContext(rule, propertyName)),
                true
            };

            //Invoke extension method with validator instance
            var documentationInstance = Activator.CreateInstance(coreDocumentationType, ruleBuilder);
            var nestedRules           = getRulesMethodDefinition.Invoke(documentationInstance, parameterArray) as IEnumerable <RuleDescription>;

            if (nestedRules == null)
            {
                yield return(null);
            }

            foreach (var deepDocumentRule in nestedRules)
            {
                yield return(deepDocumentRule);
            }
        }
Example #2
0
        public string GetErrorMessage(IPropertyValidator validator, PropertyRule rule, string propertyName)
        {
            if (validator == null)
            {
                throw new ArgumentNullException(nameof(validator));
            }

            if (rule == null)
            {
                throw new ArgumentNullException(nameof(rule));
            }

            if (string.IsNullOrWhiteSpace(propertyName))
            {
                throw new ArgumentNullException(nameof(propertyName));
            }

            const string messagePreparationMethodIdentifier    = "PrepareMessageFormatterForValidationError";
            const string createValidationErrorMethodIdentifier = "CreateValidationError";

            var validatorMethods = validator.GetType().ExtractMethodInfo(new[] { messagePreparationMethodIdentifier, createValidationErrorMethodIdentifier });

            if (validatorMethods == null)
            {
                return(null);
            }

            //ValidatorContext is based on the type passed into the validator that is validated against, such as a 'Person' POCO
            var validatorContext = _fluentValidationHelper.BuildPropertyValidatorContext(rule, propertyName);

            //Force the validator to populate field parameter names that are used as part of the error response
            validatorMethods[messagePreparationMethodIdentifier].Invoke(validator, new object[] { validatorContext });

            //With the parameter names completed, build the error using the Validator instance
            var validationFailure = validatorMethods[createValidationErrorMethodIdentifier].Invoke(validator, new object[] { validatorContext }) as ValidationFailure;

            return(validationFailure?.ErrorMessage);
        }