示例#1
0
        public static void AddDependencies(this IValidationContext context, string property, IEnumerable <LambdaExpression> expressions)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (property == null)
            {
                throw new ArgumentNullException(nameof(property));
            }
            if (expressions == null)
            {
                throw new ArgumentNullException(nameof(expressions));
            }

            if (!(context.RootContextData.TryGetValue(DependenciesKey, out var value) && value is Dictionary <string, HashSet <string> > dependencies))
            {
                context.RootContextData [DependenciesKey] = dependencies = new Dictionary <string, HashSet <string> > ( );
            }

            if (!dependencies.TryGetValue(property, out var dependents))
            {
                dependencies [property] = dependents = new HashSet <string> ( );
            }

            foreach (var expression in expressions)
            {
                dependents.Add(context.PropertyChain.BuildPropertyName(PropertyChain.FromExpression(expression).ToString( )));
            }
        }
        public void Creates_from_expression()
        {
            Expression <Func <Person, int> > expr = x => x.Address.Id;
            var chain = PropertyChain.FromExpression(expr);

            chain.ToString().ShouldEqual("Address.Id");
        }
        /// <summary>
        /// validate as an asynchronous operation.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="cancellation">The cancellation.</param>
        /// <returns>Task{IEnumerable{ValidationFailure}}.</returns>
        public override async Task <IEnumerable <ValidationFailure> > ValidateAsync(
            [NotNull] PropertyValidatorContext context,
            CancellationToken cancellation
            )
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // bail out if the property is null
            if (context.PropertyValue == null || !(context.PropertyValue is T value))
            {
                return(Enumerable.Empty <ValidationFailure>());
            }

            var validator = _validatorFactory.GetValidator(value.GetType());

            if (context.ParentContext.IsChildCollectionContext)
            {
                return((await validator.ValidateAsync(
                            context.ParentContext.CloneForChildValidator(value),
                            cancellation
                            ).ConfigureAwait(false)).Errors);
            }

            var validationContext = new ValidationContext <T>(
                value,
                PropertyChain.FromExpression(context.Rule.Expression),
                context.ParentContext.Selector
                );

            validationContext.SetServiceProvider(_serviceProvider);
            return((await validator.ValidateAsync(validationContext, cancellation).ConfigureAwait(false)).Errors);
        }
示例#4
0
        private static string DefaultPropertyNameResolver(Type type, MemberInfo memberInfo, LambdaExpression expression)
        {
            if (expression == null)
            {
                return(memberInfo != null ? memberInfo.Name : null);
            }
            var chain = PropertyChain.FromExpression(expression);

            if (chain.Count > 0)
            {
                return(chain.ToString());
            }

            return(memberInfo != null ? memberInfo.Name : null);
        }
    public static IRuleBuilderOptions <TModel, TProperty> ApplyChainValidation <TModel, TProperty>(this IRuleBuilderOptions <TModel, TProperty> builder, Expression <Func <TModel, TProperty> > expr)
    {
        // with name string
        var firstMember = PropertyChain.FromExpression(expr).ToString().Split('.')[0];     // PropertyChain is internal FluentValidation class
        // create stack to collect model properties from property chain since parents to childs to check for null in appropriate order
        var reversedExpressions = new Stack <Expression>();
        var getMemberExp        = new Func <Expression, MemberExpression>(toUnwrap =>
        {
            if (toUnwrap is UnaryExpression)
            {
                return(((UnaryExpression)toUnwrap).Operand as MemberExpression);
            }
            return(toUnwrap as MemberExpression);
        });     // lambda from PropertyChain implementation
        var memberExp    = getMemberExp(expr.Body);
        var firstSkipped = false;

        // check only parents of property to validate
        while (memberExp != null)
        {
            if (firstSkipped)
            {
                reversedExpressions.Push(memberExp);     // don't check target property for null
            }
            firstSkipped = true;
            memberExp    = getMemberExp(memberExp.Expression);
        }
        // build expression that check parent properties for null
        var currentExpr = reversedExpressions.Pop();
        var whenExpr    = Expression.NotEqual(currentExpr, Expression.Constant(null));

        while (reversedExpressions.Count > 0)
        {
            whenExpr    = Expression.AndAlso(whenExpr, Expression.NotEqual(currentExpr, Expression.Constant(null)));
            currentExpr = reversedExpressions.Pop();
        }
        var parameter = expr.Parameters.First();
        var lambda    = Expression.Lambda <Func <TModel, bool> >(whenExpr, parameter); // use parameter of source expression
        var compiled  = lambda.Compile();

        return(builder
               .WithName(firstMember)
               .When(model => compiled.Invoke(model)));
    }
 public static ValidationResult StrictlyFor <T> (this ValidationResult validationResult, params Expression <Func <T, object?> > [] properties)
 {
     return(validationResult.For(properties.Select(property => PropertyChain.FromExpression(property).ToString( )).ToArray( ), false));
 }
 public static ValidationResult StrictlyFor <T> (this ValidationResult validationResult, Expression <Func <T, object?> > property)
 {
     return(validationResult.For(PropertyChain.FromExpression(property).ToString( ), false));
 }