/// <summary> /// Specifies an asynchronous condition limiting when the validator should not run. /// The validator will only be executed if the result of the lambda returns false. /// </summary> /// <param name="rule">The current rule</param> /// <param name="predicate">A lambda expression that specifies a condition for when the validator should not run</param> /// <param name="applyConditionTo">Whether the condition should be applied to the current rule or all rules in the chain</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> UnlessAsync <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Func <T, CancellationToken, Task <bool> > predicate, ApplyConditionTo applyConditionTo = ApplyConditionTo.AllValidators) { predicate.Guard("A predicate must be specified when calling UnlessAsync"); return(rule.WhenAsync((x, ct) => predicate(x, ct).Then(y => !y, ct), applyConditionTo)); }
/// <summary> /// Specifies a custom error message resource to use when validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="resourceSelector">The resource to use as an expression, eg () => Messages.MyResource</param> /// <param name="resourceAccessorBuilder">The resource accessor builder to use. </param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithLocalizedMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Expression <Func <string> > resourceSelector, IResourceAccessorBuilder resourceAccessorBuilder) { resourceSelector.Guard("An expression must be specified when calling WithLocalizedMessage, eg .WithLocalizedMessage(() => Messages.MyResource)"); return(rule.Configure(config => { config.CurrentValidator.ErrorMessageSource = LocalizedStringSource.CreateFromExpression(resourceSelector, resourceAccessorBuilder); })); }
/// <summary> /// Specifies a localized name for the error message. /// </summary> /// <param name="rule">The current rule</param> /// <param name="resourceSelector">The resource to use as an expression, eg () => Messages.MyResource</param> /// <param name="resourceAccessorBuilder">Resource accessor builder to use</param> public static IRuleBuilderOptions <T, TProperty> WithLocalizedName <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Expression <Func <string> > resourceSelector, IResourceAccessorBuilder resourceAccessorBuilder = null) { resourceSelector.Guard("A resource selector must be specified."); // default to the static resource accessor builder - explicit resources configured with WithLocalizedName should take precedence over ResourceProviderType. resourceAccessorBuilder = resourceAccessorBuilder ?? new StaticResourceAccessorBuilder(); return(rule.Configure(config => { config.CustomPropertyName = LocalizedStringSource.CreateFromExpression(resourceSelector, resourceAccessorBuilder); })); }
public static IRuleBuilderOptions <T, TProperty> WithHttpStatusCode <T, TProperty>( this IRuleBuilderOptions <T, TProperty> ruleBuilder, HttpStatusCode httpStatusCode) { return(ruleBuilder.WithErrorCode(((int)httpStatusCode).ToString())); }
/// <summary> /// Specifies a custom error message resource to use when validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="resourceSelector">The resource to use as an expression, eg () => Messages.MyResource</param> /// <param name="formatArgs">Custom message format args</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithLocalizedMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Expression <Func <string> > resourceSelector, params object[] formatArgs) { var funcs = ConvertArrayOfObjectsToArrayOfDelegates <T>(formatArgs); return(rule.WithLocalizedMessage(resourceSelector, funcs)); }
/// <summary> /// Specifies a custom action to be invoked when the validator fails. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="rule"></param> /// <param name="onFailure"></param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> OnAnyFailure <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Action <T> onFailure) { return(rule.Configure(config => { config.OnFailure = onFailure.CoerceToNonGeneric(); })); }
/// <summary> /// Specifies a custom error message to use if validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="errorMessage">The error message to use</param> /// <param name="formatArgs">Additional arguments to be specified when formatting the custom error message.</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, string errorMessage, params object[] formatArgs) { var funcs = ConvertArrayOfObjectsToArrayOfDelegates <T>(formatArgs); return(rule.WithMessage(errorMessage, funcs)); }
public static IRuleBuilderOptions <T, string> MustBeAUrl <T>(this IRuleBuilderOptions <T, string> builder) { return(builder.Must(ValidationHelpers.Url).WithMessage("Invalid URL")); }
public static IRuleBuilderOptions <T, TProperty> WithFormattedMessage <T, TProperty, TError>(this IRuleBuilderOptions <T, TProperty> rule , TError errorMessage , params object[] args ) where TError : struct { var(id, name, descr) = errorMessage.ConvertToEnumTuple(); // choose what to send back here // currently: formatted description // if just 'code' needed : replace 'descr' with 'name' (name don't contain any {}) var formatter = descr; var message = FormatMessage(formatter, args); return(rule.WithMessage(FormatMessage(formatter, args))); }
public override IRuleBuilderOptions <TContainer, string> Validate <TContainer>(IRuleBuilderOptions <TContainer, string> builder) { return(builder.NotEmpty()); }
public static IRuleBuilderOptions <T, TElement> AllowedFileExtensionsAre <T, TElement>( this IRuleBuilderOptions <T, TElement> ruleBuilder, bool isCollection = false, params string[] extensions) => ruleBuilder.Must(upload => isCollection switch
/// <summary> /// Overrides the name of the property associated with this rule. /// NOTE: This is a considered to be an advanced feature. 99% of the time that you use this, you actually meant to use WithName. /// </summary> /// <param name="rule">The current rule</param> /// <param name="propertyName">The property name to use</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> OverridePropertyName <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, string propertyName) { // Allow string.Empty as this could be a model-level rule. if (propertyName == null) { throw new ArgumentNullException(nameof(propertyName), "A property name must be specified when calling OverridePropertyName."); } return(rule.Configure(config => config.PropertyName = propertyName)); }
/// <summary> /// Triggers an action when the rule passes. Typically used to configure dependent rules. This applies to all preceding rules in the chain. /// </summary> /// <param name="rule">The current rule</param> /// <param name="action">An action to be invoked if the rule is valid</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> DependentRules <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Action action) { var dependencyContainer = new List <IValidationRule>(); if (rule is IExposesParentValidator <T> exposesParentValidator) { if (exposesParentValidator.ParentValidator is AbstractValidator <T> parent) { // Capture any rules added to the parent validator inside this delegate. using (parent.NestedValidators.Capture(dependencyContainer.Add)) { action(); } } } else { throw new NotSupportedException("DependentRules can only be called as part of classes that inherit from AbstractValidator"); } rule.Configure(cfg => { if (!string.IsNullOrEmpty(cfg.RuleSet)) { foreach (var dependentRule in dependencyContainer) { if (dependentRule is PropertyRule propRule && string.IsNullOrEmpty(propRule.RuleSet)) { propRule.RuleSet = cfg.RuleSet; } } } cfg.DependentRules.AddRange(dependencyContainer); }); return(rule); }
public static IRuleBuilderOptions <T, TProperty> DependentRules <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Action <IValidator <T> > action) { var dependencyContainer = new InlineValidator <T>(); if (rule is IExposesParentValidator <T> exposesParentValidator) { if (exposesParentValidator.ParentValidator is AbstractValidator <T> parent) { // Capture any rules added to the parent validator inside this delegate. using (parent.NestedValidators.Capture(dependencyContainer.AddRule)) { action(dependencyContainer); } } } else { action(dependencyContainer); } rule.Configure(cfg => { if (!string.IsNullOrEmpty(cfg.RuleSet)) { foreach (var dependentRule in dependencyContainer) { var propRule = dependentRule as PropertyRule; if (propRule != null && string.IsNullOrEmpty(propRule.RuleSet)) { propRule.RuleSet = cfg.RuleSet; } } } cfg.DependentRules.AddRange(dependencyContainer); }); return(rule); }
/// <summary> /// Specifies custom state that should be stored alongside the validation message when validation fails for this rule. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="rule"></param> /// <param name="stateProvider"></param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithState <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Func <T, object> stateProvider) { stateProvider.Guard("A lambda expression must be passed to WithState"); return(rule.Configure(config => config.CurrentValidator.CustomStateProvider = stateProvider.CoerceToNonGeneric())); }
public static IRuleBuilderOptions <T, TProperty> WithMessage <T, TProperty, TError>(this IRuleBuilderOptions <T, TProperty> rule , TError errorMessage , params object[] args ) where TError : struct { var(_, _, descr) = errorMessage.ConvertToEnumTuple(); return(rule.WithMessage(descr)); }
/// <summary> /// Specifies custom severity that should be stored alongside the validation message when validation fails for this rule. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="rule"></param> /// <param name="severity"></param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithSeverity <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Severity severity) { return(rule.Configure(config => config.CurrentValidator.Severity = severity)); }
public static IRuleBuilderOptions <T, TProperty> WithErrorCode <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, int code) { return(rule.WithState(x => code)); }
/// <summary> /// Specifies a custom error message to use if validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="errorMessage">The error message to use</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, string errorMessage) { return(rule.WithMessage(errorMessage, null as object[])); }
/// <summary> /// Specifies a custom error code to use if validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="errorCode">The error code to use</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithErrorCode <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, string errorCode) { errorCode.Guard("A error code must be specified when calling WithErrorCode."); return(rule.Configure(config => { config.CurrentValidator.ErrorCodeSource = new StaticStringSource(errorCode); })); }
public static IRuleBuilderOptions <T, TProp> AsWarning <T, TProp>(this IRuleBuilderOptions <T, TProp> ruleBuilder) { return(ruleBuilder.WithState(v => NzbDroneValidationState.Warning)); }
/// <summary> /// Specifies a custom error message resource to use when validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="resourceSelector">The resource to use as an expression, eg () => Messages.MyResource</param> /// <param name="resourceName">Name of resource</param> /// <param name="formatArgs">Custom message format args</param> /// <param name="resourceType">Type of resource representing a resx file</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithLocalizedMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Type resourceType, string resourceName, params object[] formatArgs) { var funcs = ConvertArrayOfObjectsToArrayOfDelegates <T>(formatArgs); return(rule.WithLocalizedMessage(resourceType, resourceName, funcs)); }
/// <summary> /// Specifies a custom error message resource to use when validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="resourceSelector">The resource to use as an expression, eg () => Messages.MyResource</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithLocalizedMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Expression <Func <string> > resourceSelector) { // We use the StaticResourceAccessorBuilder here because we don't want calls to WithLocalizedMessage to be overriden by the ResourceProviderType. return(rule.WithLocalizedMessage(resourceSelector, new StaticResourceAccessorBuilder())); }
/// <summary> /// Specifies a custom error message resource to use when validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="resourceType">Resource type representing a resx file</param> /// <param name="resourceName">Name of resource</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithLocalizedMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Type resourceType, string resourceName) { resourceType.Guard("A resource type must be provided."); resourceName.Guard("A resource name must be provided."); return(rule.Configure(config => { config.CurrentValidator.ErrorMessageSource = new LocalizedStringSource(resourceType, resourceName, new StaticResourceAccessorBuilder()); })); }
/// <summary> /// Specifies a custom error message resource to use when validation fails. /// </summary> /// <param name="rule">The current rule</param> /// <param name="resourceSelector">The resource to use as an expression, eg () => Messages.MyResource</param> /// <param name="formatArgs">Custom message format args</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> WithLocalizedMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Expression <Func <string> > resourceSelector, params Func <T, object>[] formatArgs) { // We use the StaticResourceAccessorBuilder here because we don't want calls to WithLocalizedMessage to be overriden by the ResourceProviderType. return(rule.WithLocalizedMessage(resourceSelector, new StaticResourceAccessorBuilder()) .Configure(cfg => { formatArgs .Select(func => new Func <object, object>(x => func((T)x))) .ForEach(cfg.CurrentValidator.CustomMessageFormatArguments.Add); })); }
/// <summary> /// Triggers an action when the rule passes. Typically used to configure dependent rules. This applies to all preceding rules in the chain. /// </summary> /// <param name="rule">The current rule</param> /// <param name="action">An action to be invoked if the rule is valid</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> DependentRules <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Action <DependentRules <T> > action) { var dependencyContainer = new DependentRules <T>(); action(dependencyContainer); rule.Configure(cfg => { if (!string.IsNullOrEmpty(cfg.RuleSet)) { foreach (var dependentRule in dependencyContainer) { var propRule = dependentRule as PropertyRule; if (propRule != null && string.IsNullOrEmpty(propRule.RuleSet)) { propRule.RuleSet = cfg.RuleSet; } } } cfg.DependentRules.AddRange(dependencyContainer); }); return(rule); }
/// <summary> /// Specifies a condition limiting when the validator should not run. /// The validator will only be executed if the result of the lambda returns false. /// </summary> /// <param name="rule">The current rule</param> /// <param name="predicate">A lambda expression that specifies a condition for when the validator should not run</param> /// <param name="applyConditionTo">Whether the condition should be applied to the current rule or all rules in the chain</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> Unless <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Func <T, bool> predicate, ApplyConditionTo applyConditionTo = ApplyConditionTo.AllValidators) { predicate.Guard("A predicate must be specified when calling Unless"); return(rule.When(x => !predicate(x), applyConditionTo)); }
public static IRuleBuilderOptions <T, TProperty> WithPropertyName <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, string propertyName) { return(rule.OverridePropertyName(propertyName)); }
/// <summary> /// Overrides the name of the property associated with this rule. /// NOTE: This is a considered to be an advanced feature. 99% of the time that you use this, you actually meant to use WithName. /// </summary> /// <param name="rule">The current rule</param> /// <param name="propertyName">The property name to use</param> /// <returns></returns> public static IRuleBuilderOptions <T, TProperty> OverridePropertyName <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, string propertyName) { propertyName.Guard("A property name must be specified when calling WithNamePropertyName."); return(rule.Configure(config => config.PropertyName = propertyName)); }
public static IRuleBuilderOptions <T, TProperty> WithLocalizedMessage <T, TProperty>(this IRuleBuilderOptions <T, TProperty> rule, Expression <Func <string> > resourceSelector, params Func <T, object>[] formatArgs) { // We use the StaticResourceAccessorBuilder here because we don't want calls to WithLocalizedMessage to be overriden by the ResourceProviderType. return(rule.Configure(config => { var funcs = formatArgs .Select(func => new Func <object, object, object>((instance, value) => func((T)instance))).ToList(); config.CurrentValidator.ErrorMessageSource = new BackwardsCompatFormatArgStringSource(LocalizedStringSource.CreateFromExpression(resourceSelector, null), funcs);; })); }