/// <summary> /// Selects all elements of a `IEnumerable` property for validation. /// </summary> /// <typeparam name="T">The type of the current value.</typeparam> /// <typeparam name="TItem">The type of an individual item in the `IEnumerable` property.</typeparam> /// <param name="validator">The current validator context.</param> /// <param name="selector"> /// The property selector expression. /// <para> /// The expression must be a `MemberExpression` (e.g. `x => x.Property`) or a `ParameterExpression` /// to select all elements of the current value (e.g. `x => x`). /// </para> /// </param> /// <param name="action">The action to perform for each item of the selected `IEnumerable` property.</param> /// <returns>The unmodified validator context.</returns> public static IValidatorContext <T> ForEach <T, TItem>(this IValidatorContext <T> validator, Expression <Func <T, IEnumerable <TItem> > > selector, Action <IValidatorContext <TItem> > action) { ValidationInternals.ValidateNotNull(validator, nameof(validator)); ValidationInternals.ValidateNotNull(selector, nameof(selector)); ValidationInternals.ValidateNotNull(action, nameof(action)); var name = (selector.Body is ParameterExpression) ? null : ValidationInternals.GetPropertyName(selector); var value = selector.Compile().Invoke(validator.Value); if (value is null) { return(validator); } int i = 0; foreach (var item in value) { var context = (name is null) ? new ValidatorContext <TItem>(item, $"{ValidationInternals.FormatName(validator.Path, null)}[{i++}]") : new ValidatorContext <TItem>(item, validator.Path, $"{name}[{i++}]"); action.Invoke(context); } return(validator); }
/// <summary> /// Selects a property for validation. /// </summary> /// <typeparam name="T">The type of the current value.</typeparam> /// <typeparam name="TNext">The type of the selected property.</typeparam> /// <param name="validator">The current validator context.</param> /// <param name="selector"> /// The property selector expression. /// <para> /// The expression must be a `MemberExpression` (e.g. `x => x.Property`). /// </para> /// </param> /// <param name="action">The action to perform for the selected property.</param> /// <returns>The unmodified validator context.</returns> public static IValidatorContext <T> For <T, TNext>(this IValidatorContext <T> validator, Expression <Func <T, TNext> > selector, Action <IValidatorContext <TNext> > action) { ValidationInternals.ValidateNotNull(validator, nameof(validator)); ValidationInternals.ValidateNotNull(selector, nameof(selector)); ValidationInternals.ValidateNotNull(action, nameof(action)); var name = ValidationInternals.GetPropertyName(selector); var value = selector.Compile().Invoke(validator.Value); var context = new ValidatorContext <TNext>(value, validator.Path, name); action.Invoke(context); return(validator); }