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); }
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)); }