public async Task ValidateAsync(IValidatableViewModel context, PropertyInfo sender, bool validateAll) { this.Error.Clear(); for (int i = 0; i < this.Count; i++) { var item = this[i]; // Dont invoke these kind of validators if (!ValidationHandler.IgnoreAlwaysValidate && !item.AlwaysValidate && sender == null && !validateAll) { continue; } var error = await item.ValidateAsync(sender, context); if (!string.IsNullOrEmpty(error)) { this.Error.Push(error); if (!ValidationHandler.StopValidationOnError) { break; } } } }
/// <summary> /// Invokes the validation on the specified context with the specified parameters /// </summary> /// <param name="sender">The property that invoked the validation</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> of the validated property</param> /// <param name="value">The value of the property</param> /// <returns>Has to return true on validation error otherwise false</returns> protected override Task <bool> OnValidateAsync(PropertyInfo sender, IValidatableViewModel context, PropertyInfo propertyInfo, object value) { // if the value is null, then we should return a validation successfull, so that it is // possible to have non mandatory inputs if (value == null) { return(Task.FromResult(false)); } if (this.value != null) { return(Task.FromResult(!Comparer.GreaterThanOrEqual(value, this.value))); } var otherProperty = context.GetType().GetPropertyEx(this.propertyName); if (otherProperty == null) { throw new ArgumentException(string.Format("The property '{0}' was not found on '{1}'.", this.propertyName, context.GetType().FullName)); } // Also same for this value var comparisonValue = otherProperty.GetValue(context); if (comparisonValue == null) { return(Task.FromResult(false)); } return(Task.FromResult(!Comparer.GreaterThanOrEqual(value, comparisonValue))); }
/// <summary> /// Invokes the validation on the specified context with the specified parameters /// </summary> /// <param name="sender">The property that invoked the validation</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> of the validated property</param> /// <param name="value">The value of the property</param> /// <returns>Has to return true on validation error otherwise false</returns> protected override Task <bool> OnValidateAsync(PropertyInfo sender, IValidatableViewModel context, PropertyInfo propertyInfo, object value) { if (this.isEnabledPropertyName != null && !this.IsEnabled(context, propertyInfo)) { return(Task.FromResult(false)); } if (value == null) { return(Task.FromResult(true)); } if (propertyInfo.PropertyType == typeof(string)) { return(Task.FromResult(string.IsNullOrEmpty(value.ToString()))); } if (propertyInfo.PropertyType == typeof(bool)) { return(Task.FromResult(!(bool)value)); } if (value is IEnumerable && (value as IEnumerable).Operations().Count() == 0) { return(Task.FromResult(true)); } if (propertyInfo.PropertyType == typeof(SecureString)) { return(Task.FromResult((value as SecureString).Length == 0)); } return(Task.FromResult(false)); }
/// <summary> /// Occures on validation /// <para/> /// Can be used to modify the validation error message. /// </summary> /// <param name="errorMessage">The validation error message</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <returns>A modified validation error message</returns> protected override string ValidationMessage(string errorMessage, IValidatableViewModel context) { var otherProperty = context.GetType().GetPropertyEx(this.otherProperty); if (otherProperty == null) { return(errorMessage); } return(errorMessage.ToString(otherProperty.GetValue(context))); }
/// <summary> /// Invokes the validation on the specified context with the specified parameters /// </summary> /// <param name="sender">The property that invoked the validation</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <returns>Returns the error message if validation fails. Empty if successful</returns> internal async Task <string> ValidateAsync(PropertyInfo sender, IValidatableViewModel context) { var value = this.propertyInfo.GetValue(context); if (await this.OnValidateAsync(sender, context, propertyInfo, value)) { return(this.ValidationMessage(Locale.Current[this.ErrorMessageKey], context)); } return(string.Empty); }
/// <summary> /// Registers an <see cref="IValidationComponent"/> into the <see cref="ValidationContext"/> /// of the specified <see cref="IValidatableViewModel"/>. Disposes and removes the /// <see cref="IValidationComponent"/> from the <see cref="ValidationContext"/> when the /// <see cref="ValidationHelper"/> is disposed. /// </summary> /// <param name="viewModel">The validatable view model holding a reference to the context.</param> /// <param name="validation">The disposable validation component to register into the context.</param> /// <typeparam name="TValidationComponent">The disposable validation component type.</typeparam> /// <returns>The bindable validation helper holding the disposable.</returns> private static ValidationHelper RegisterValidation <TValidationComponent>( this IValidatableViewModel viewModel, TValidationComponent validation) where TValidationComponent : IValidationComponent, IDisposable { viewModel.ValidationContext.Add(validation); return(new ValidationHelper(validation, Disposable.Create(() => { viewModel.ValidationContext.Remove(validation); validation.Dispose(); }))); }
/// <summary> /// Invokes the validation on the specified context with the specified parameters /// </summary> /// <param name="sender">The property that invoked the validation</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> of the validated property</param> /// <param name="value">The value of the property</param> /// <returns>Has to return true on validation error otherwise false</returns> protected override Task <bool> OnValidateAsync(PropertyInfo sender, IValidatableViewModel context, PropertyInfo propertyInfo, object value) { var strength = PasswordScore.Blank; var password = string.Empty; if (propertyInfo.PropertyType == typeof(string)) { strength = CryptoUtils.GetPasswordScore(password); } return(Task.FromResult(strength == PasswordScore.Blank || strength == PasswordScore.VeryWeak || strength == PasswordScore.Weak)); }
/// <summary> /// Invokes the validation on the specified context with the specified parameters /// </summary> /// <param name="sender">The property that invoked the validation</param> /// <param name="context">The viewmodel context that has to be validated</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> of the validated property</param> /// <param name="value">The value of the property</param> /// <returns>Has to return true on validation error otherwise false</returns> protected override async Task <bool> OnValidateAsync(PropertyInfo sender, IValidatableViewModel context, PropertyInfo propertyInfo, object value) { // if the value is null, then we should return a validation successfull, so that it is // possible to have non mandatory inputs if (value == null) { return(false); } var secondProperty = context.GetType().GetPropertyEx(this.otherProperty); if (secondProperty == null) { return(true); } var secondValue = secondProperty.GetValue(context); if (sender == null) { await context.ValidateAsync(propertyInfo, secondProperty.Name); } if (value is SecureString && (secondValue is SecureString || secondValue == null)) { var ssa = value as SecureString; var ssb = secondValue as SecureString; if (ssa.Length == 0 && ssb == null) { return(true); } if (ssa.Length != 0 && ssb == null) { return(false); } return(ssa.IsEqualTo(ssb)); } if (secondValue == null) { return(false); } return(!Comparer.Equals(value, secondValue)); }
/// <summary> /// Invokes the validation on the specified context with the specified parameters /// </summary> /// <param name="sender">The property that invoked the validation</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> of the validated property</param> /// <param name="value">The value of the property</param> /// <returns>Has to return true on validation error otherwise false</returns> protected override Task <bool> OnValidateAsync(PropertyInfo sender, IValidatableViewModel context, PropertyInfo propertyInfo, object value) { if (propertyInfo.PropertyType != typeof(string)) { throw new ArgumentException("The StringLengthAttribute can only be applied to a string"); } var str = value as string; if (str == null) { return(Task.FromResult(true)); } var length = str.Length; return(Task.FromResult(length < this.minLength || length > this.maxLength)); }
/// <summary> /// Occures on validation /// <para/> /// Can be used to modify the validation error message. /// </summary> /// <param name="errorMessage">The validation error message</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <returns>A modified validation error message</returns> protected override string ValidationMessage(string errorMessage, IValidatableViewModel context) => errorMessage.ToString(minLength, maxLength);
/// <summary> /// Occures on validation /// <para/> /// Can be used to modify the validation error message. /// </summary> /// <param name="errorMessage">The validation error message</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <returns>A modified validation error message</returns> protected virtual string ValidationMessage(string errorMessage, IValidatableViewModel context) => errorMessage;
/// <summary> /// Invokes the validation on the specified context with the specified parameters /// </summary> /// <param name="sender">The property that invoked the validation</param> /// <param name="context">The Viewmodel context that has to be validated</param> /// <param name="propertyInfo">The <see cref="PropertyInfo"/> of the validated property</param> /// <param name="value">The value of the property</param> /// <returns>Has to return true on validation error otherwise false</returns> protected abstract Task <bool> OnValidateAsync(PropertyInfo sender, IValidatableViewModel context, PropertyInfo propertyInfo, object value);