/// <summary> /// Creates an instance of <see cref = "ValidationAttributeValidator" /> class. /// </summary> /// <param name = "validationAttribute"> /// Validation attribute used to validate a property or an entity. /// </param> public ValidationAttributeValidator(ValidationAttribute validationAttribute, DisplayAttribute displayAttribute) { //Contract.Requires(validationAttribute != null); _validationAttribute = validationAttribute; _displayAttribute = displayAttribute; }
/// <summary> /// Create client validation rules for Data Annotation attributes. /// </summary> /// <param name="attribute">Attribute</param> /// <param name="errorMessage">Not formatted error message (should contain {0} etc}</param> /// <returns>A collection of rules (or an empty collection)</returns> public virtual IEnumerable<ModelClientValidationRule> Create(ValidationAttribute attribute, string errorMessage) { if (attribute is RangeAttribute) { var attr = (RangeAttribute) attribute; return new[] { new ModelClientValidationRangeRule(errorMessage, attr.Minimum, attr.Maximum) }; } if (attribute is RegularExpressionAttribute) { var attr = (RegularExpressionAttribute) attribute; return new[] {new ModelClientValidationRegexRule(errorMessage, attr.Pattern)}; } if (attribute is RequiredAttribute) { var attr = (RequiredAttribute) attribute; return new[] {new ModelClientValidationRequiredRule(errorMessage)}; } if (attribute is StringLengthAttribute) { var attr = (StringLengthAttribute) attribute; return new[] { new ModelClientValidationStringLengthRule(errorMessage, attr.MinimumLength, attr.MaximumLength) }; } return new ModelClientValidationRule[0]; }
public ViewModelPropertyValidationRule(string clientRule, ValidationAttribute sourceValidationAttribute, string errorMessage, params object[] parameters) { ClientRuleName = clientRule; SourceValidationAttribute = sourceValidationAttribute; ErrorMessage = errorMessage; Parameters = parameters; }
/// <summary> /// Gets the rules the adapter provides. /// </summary> /// <param name="attribute">The <see cref="ValidationAttribute"/> that should be handled.</param> /// <param name="descriptor">A <see cref="PropertyDescriptor"/> instance for the property that is being validated.</param> /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="ModelValidationRule"/> instances.</returns> public override IEnumerable<ModelValidationRule> GetRules(ValidationAttribute attribute, PropertyDescriptor descriptor) { yield return new StringLengthValidationRule(attribute.FormatErrorMessage, new[] { descriptor.Name }, ((StringLengthAttribute)attribute).MinimumLength, ((StringLengthAttribute)attribute).MaximumLength); }
public static void GetAttributeValidation(ValidationAttribute attr, IDictionary<string, object> htmlAttributes) { var str = string.Empty; if (attr is RequiredAttribute) { StringLengthAttribute a = attr as StringLengthAttribute; htmlAttributes["required"] = null; } else if (attr is StringLengthAttribute) { StringLengthAttribute a = attr as StringLengthAttribute; htmlAttributes["maxlength"] = a.MaximumLength; htmlAttributes["minlength"] = a.MinimumLength; } else if (attr is RegularExpressionAttribute) { RegularExpressionAttribute a = attr as RegularExpressionAttribute; htmlAttributes["pattern"] = a.Pattern; } else if (attr is IdenticalAttribute) { IdenticalAttribute a = attr as IdenticalAttribute; htmlAttributes["data-fv-identical"] = "true"; htmlAttributes["data-fv-identical-field"] = a.Field; } if (attr.ErrorMessage.IsNotNull()) { htmlAttributes[ ValidateMesAttr[attr.GetType()]]= attr.ErrorMessage; } }
public MyValidator(ValidationAttribute attribute, string errorMsg, ModelMetadata metadata, ControllerContext controllerContext, IEnumerable<ModelClientValidationRule> create) : base(metadata, controllerContext) { _attribute = attribute; _errorMsg = errorMsg; _create = create; }
// <summary> // Creates an instance of <see cref="ValidationAttributeValidator" /> class. // </summary> // <param name="validationAttribute"> Validation attribute used to validate a property or an entity. </param> public ValidationAttributeValidator(ValidationAttribute validationAttribute, DisplayAttribute displayAttribute) { DebugCheck.NotNull(validationAttribute); _validationAttribute = validationAttribute; _displayAttribute = displayAttribute; }
public DynamoDataAnnotationsModelValidator(IServiceProvider provider, ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) : base(metadata, context, attribute) { if (provider == null) throw new ArgumentNullException("provider"); _provider = provider; }
/// <summary> /// Initializes a new instance of the AttributeValidationItem class. /// </summary> /// <param name="attribute"></param> /// <param name="propertyName"></param> public AttributeValidationItem(ValidationAttribute attribute, string propertyName) { if (attribute == null) throw new ArgumentNullException("attribute", "attribute is null."); if (String.IsNullOrEmpty(propertyName)) throw new ArgumentException("propertyName is null or empty.", "propertyName"); _attribute = attribute; _propertyName = propertyName; }
public DataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) : base(metadata, context) { if (attribute == null) { throw new ArgumentNullException("attribute"); } Attribute = attribute; }
protected virtual void HandleErrorMessage(string languageKey, ValidationAttribute attribute) { if (attribute.ErrorMessageResourceName == null) { attribute.ErrorMessage = LangResource.Resources.GetString(languageKey); if (string.IsNullOrEmpty(attribute.ErrorMessage)) attribute.ErrorMessage = string.Format("[[{0}]]", languageKey); } }
public DataAnnotationsModelValidator(IEnumerable<ModelValidatorProvider> validatorProviders, ValidationAttribute attribute) : base(validatorProviders) { if (attribute == null) { throw Error.ArgumentNull("attribute"); } Attribute = attribute; }
public DataAnnotationsModelValidator(ValidationAttribute attribute, IStringLocalizer stringLocalizer) { if (attribute == null) { throw new ArgumentNullException(nameof(attribute)); } Attribute = attribute; _stringLocalizer = stringLocalizer; }
public static IEnumerable<string> GetErrorMessages(ValidationAttribute[] attributes, object value, ValidationContext context) { var errorMessages = attributes .Select(v => v.GetValidationResult(value, context)) .Where(r => r != null) .Select(r => r.ErrorMessage) .Where(e => !string.IsNullOrEmpty(e)); return errorMessages; }
public void AdapterFactory_RegistersAdapters_ForDataAnnotationAttributes( ValidationAttribute attribute, Type expectedAdapterType) { // Arrange and Act var adapter = _validationAttributeAdapterProvider.GetAttributeAdapter(attribute, stringLocalizer: null); // Assert Assert.IsType(expectedAdapterType, adapter); }
/// <summary> /// Gets the rules the adapter provides. /// </summary> /// <param name="attribute">The <see cref="ValidationAttribute"/> that should be handled.</param> /// <param name="descriptor">A <see cref="PropertyDescriptor"/> instance for the property that is being validated.</param> /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="ModelValidationRule"/> instances.</returns> public override IEnumerable<ModelValidationRule> GetRules(ValidationAttribute attribute, PropertyDescriptor descriptor) { var requiredAttribute = (RequiredAttribute) attribute; yield return new NotNullValidationRule(attribute.FormatErrorMessage, new[] { descriptor.Name }); if (!requiredAttribute.AllowEmptyStrings) { yield return new NotEmptyValidationRule(attribute.FormatErrorMessage, new[] { descriptor.Name }); } }
public void AdapterFactory_RegistersAdapters_ForDataTypeAttributes( ValidationAttribute attribute, string expectedRuleName) { // Arrange & Act var adapter = _validationAttributeAdapterProvider.GetAttributeAdapter(attribute, stringLocalizer: null); // Assert var dataTypeAdapter = Assert.IsType<DataTypeAttributeAdapter>(adapter); Assert.Equal(expectedRuleName, dataTypeAdapter.RuleName); }
/// <summary> /// Initializes a new instance of the <see cref="GetMessageContext"/> class. /// </summary> /// <param name="attribute">The attribute.</param> /// <param name="containerType">Model that the property is in.</param> /// <param name="propertyName">Name of the property.</param> /// <param name="cultureInfo">Requested language.</param> public GetMessageContext(ValidationAttribute attribute, Type containerType, string propertyName, CultureInfo cultureInfo) { if (attribute == null) throw new ArgumentNullException("attribute"); if (containerType == null) throw new ArgumentNullException("containerType"); if (propertyName == null) throw new ArgumentNullException("propertyName"); if (cultureInfo == null) throw new ArgumentNullException("cultureInfo"); _attribute = attribute; _containerType = containerType; _propertyName = propertyName; _cultureInfo = cultureInfo; }
/// <summary> /// Gets the rules the adapter provides. /// </summary> /// <param name="attribute">The <see cref="ValidationAttribute"/> that should be handled.</param> /// <param name="descriptor">A <see cref="PropertyDescriptor"/> instance for the property that is being validated.</param> /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="ModelValidationRule"/> instances.</returns> public override IEnumerable<ModelValidationRule> GetRules(ValidationAttribute attribute, PropertyDescriptor descriptor) { var ra = (RangeAttribute)attribute; yield return new ComparisonValidationRule(attribute.FormatErrorMessage, new[] { descriptor.Name }, ComparisonOperator.GreaterThanOrEqual, Convert(ra.OperandType, ra.Minimum)); yield return new ComparisonValidationRule(attribute.FormatErrorMessage, new[] { descriptor.Name }, ComparisonOperator.LessThanOrEqual, Convert(ra.OperandType, ra.Maximum)); }
public CustomDataAnnotationsModelValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute) : base(metadata, context, attribute) { if (Attribute.ErrorMessageResourceType == null) { Attribute.ErrorMessageResourceType = ResourceType; } if (Attribute.ErrorMessageResourceName == null) { Attribute.ErrorMessageResourceName = ResourceNameFunc(Attribute); } }
protected void BindErrorMessageToAttribte( ValidationAttribute attribute, IStorageValidator validator, Type defaultResourceType) { if (!String.IsNullOrEmpty(validator.ErrorMessage)) { attribute.ErrorMessage = validator.ErrorMessage; return; } if (!String.IsNullOrEmpty(validator.ErrorMessageResourceName)) { attribute.ErrorMessageResourceName = validator.ErrorMessageResourceName; attribute.ErrorMessageResourceType = validator.ErrorMessageResourceType ?? defaultResourceType; } }
public IEnumerable<ModelValidationError> Validate(object instance, ValidationAttribute attribute, PropertyDescriptor descriptor, NancyContext context) { var validationContext = new ValidationContext(instance, null, null) { MemberName = ((MatchAttribute)attribute).SourceProperty }; var result = attribute.GetValidationResult(instance, validationContext); if(result != null) { yield return new ModelValidationError(result.MemberNames, attribute.ErrorMessage); } yield break; }
private ValidationAttribute CopyAttribute(ValidationAttribute attribute) { ValidationAttribute result = null; if (attribute is RangeAttribute) { var attr = (RangeAttribute)attribute; result = (attr.Minimum is double) ? new RangeAttribute((double)attr.Minimum, (double)attr.Maximum) : new RangeAttribute((int)attr.Minimum, (int)attr.Maximum); } if (attribute is RegularExpressionAttribute) { var attr = (RegularExpressionAttribute)attribute; result = new RegularExpressionAttribute(attr.Pattern); } if (attribute is RequiredAttribute) result = new RequiredAttribute(); if (attribute is StringLengthAttribute) { var attr = (StringLengthAttribute)attribute; result = new StringLengthAttribute(attr.MaximumLength) { MinimumLength = attr.MinimumLength }; } if (attribute is DA.CompareAttribute) { var attr = (DA.CompareAttribute)attribute; result = new DA.CompareAttribute(attr.OtherProperty); } if (attribute is DataTypeAttribute) { var attr = (DataTypeAttribute)attribute; result = new DataTypeAttribute(attr.DataType); } if (result == null && attribute.GetType().GetInterfaces().Contains(typeof(ICloneable))) result = ((ICloneable)attribute).Clone() as ValidationAttribute; return result; }
/// <summary> /// Registers any resource type used by the given <see cref="ValidationAttribute"/> that must be shared and /// have a named resource property available. /// </summary> /// <param name="validationAttribute">The <see cref="ValidationAttribute"/> instance to check.</param> /// <param name="attributeDeclaration">The <see cref="AttributeDeclaration"/> used to describe <paramref name="validationAttribute"/>.</param> protected static void RegisterSharedResources(ValidationAttribute validationAttribute, AttributeDeclaration attributeDeclaration) { string resourceName = validationAttribute.ErrorMessageResourceName; Type resourceType = validationAttribute.ErrorMessageResourceType; bool isEmptyResourceName = string.IsNullOrEmpty(resourceName); Type validateionAttributeType = validationAttribute.GetType(); // At least one is non-null. If the other is null, we have a problem. We need both to // localize properly, or neither to signal we use the static string version if ((resourceType != null && isEmptyResourceName) || (resourceType == null && !isEmptyResourceName)) { string resourceTypeMessage = resourceType != null ? resourceType.Name : Resource.Unspecified_Resource_Element; string resourceNameMessage = isEmptyResourceName ? Resource.Unspecified_Resource_Element : resourceName; attributeDeclaration.Errors.Add( string.Format( CultureInfo.CurrentCulture, Resource.ClientCodeGen_ValidationAttribute_Requires_ResourceType_And_Name, validateionAttributeType, resourceTypeMessage, resourceNameMessage)); return; } if (resourceType != null) { PropertyInfo resourceProperty = resourceType.GetProperty(resourceName); if (resourceProperty == null) { attributeDeclaration.Errors.Add( string.Format( CultureInfo.CurrentCulture, Resource.ClientCodeGen_ValidationAttribute_ResourcePropertyNotFound, validateionAttributeType, resourceName, resourceType)); } else { attributeDeclaration.RequiredTypes.Add(resourceType); attributeDeclaration.RequiredProperties.Add(resourceProperty); } } }
/// <summary> /// Get client rules /// </summary> /// <param name="metadata">Model meta data</param> /// <param name="context">Controller context</param> /// <param name="attr">Attribute being localized</param> /// <param name="formattedError">Localized error message</param> /// <returns>Collection (may be empty) with error messages for client side</returns> protected virtual IEnumerable<ModelClientValidationRule> GetClientRules(ModelMetadata metadata, ControllerContext context, ValidationAttribute attr, string formattedError) { var clientValidable = attr as IClientValidatable; var clientRules = clientValidable == null ? _adapterFactory.Create(attr, formattedError) : clientValidable.GetClientValidationRules( metadata, context).ToList(); foreach (var clientRule in clientRules) { clientRule.ErrorMessage = formattedError; } return clientRules; }
/// <summary> /// /// </summary> /// <param name="metadata">Model meta data</param> /// <param name="attr">Attribute to localize</param> /// <param name="errorMessage">Localized message with <c>{}</c> formatters.</param> /// <returns>Formatted message (<c>{}</c> has been replaced with values)</returns> protected virtual string FormatErrorMessage(ModelMetadata metadata, ValidationAttribute attr, string errorMessage) { string formattedError; try { lock (attr) { attr.ErrorMessage = errorMessage; formattedError = attr.FormatErrorMessage(metadata.GetDisplayName()); attr.ErrorMessage = WorkaroundMarker; } } catch (Exception err) { formattedError = err.Message; } return formattedError; }
/// <summary> /// Create a new instance of <see cref="DataAnnotationsModelValidator"/>. /// </summary> /// <param name="attribute">The <see cref="ValidationAttribute"/> that defines what we're validating.</param> /// <param name="stringLocalizer">The <see cref="IStringLocalizer"/> used to create messages.</param> /// <param name="validationAttributeAdapterProvider">The <see cref="IValidationAttributeAdapterProvider"/> /// which <see cref="ValidationAttributeAdapter{TAttribute}"/>'s will be created from.</param> public DataAnnotationsModelValidator( IValidationAttributeAdapterProvider validationAttributeAdapterProvider, ValidationAttribute attribute, IStringLocalizer stringLocalizer) { if (validationAttributeAdapterProvider == null) { throw new ArgumentNullException(nameof(validationAttributeAdapterProvider)); } if (attribute == null) { throw new ArgumentNullException(nameof(attribute)); } _validationAttributeAdapterProvider = validationAttributeAdapterProvider; Attribute = attribute; _stringLocalizer = stringLocalizer; }
public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute, IStringLocalizer localizer) { Type type = attribute.GetType(); if (type == typeof(RequiredAttribute)) return new RequiredAdapter((RequiredAttribute)attribute); if (type == typeof(StringLengthAttribute)) return new StringLengthAdapter((StringLengthAttribute)attribute); if (type == typeof(EmailAddressAttribute)) return new EmailAddressAdapter((EmailAddressAttribute)attribute); if (type == typeof(GreaterThanAttribute)) return new GreaterThanAdapter((GreaterThanAttribute)attribute); if (type == typeof(MinLengthAttribute)) return new MinLengthAdapter((MinLengthAttribute)attribute); if (type == typeof(MaxValueAttribute)) return new MaxValueAdapter((MaxValueAttribute)attribute); if (type == typeof(MinValueAttribute)) return new MinValueAdapter((MinValueAttribute)attribute); if (type == typeof(FileSizeAttribute)) return new FileSizeAdapter((FileSizeAttribute)attribute); if (type == typeof(EqualToAttribute)) return new EqualToAdapter((EqualToAttribute)attribute); if (type == typeof(IntegerAttribute)) return new IntegerAdapter((IntegerAttribute)attribute); if (type == typeof(DigitsAttribute)) return new DigitsAdapter((DigitsAttribute)attribute); if (type == typeof(RangeAttribute)) return new RangeAdapter((RangeAttribute)attribute); return null; }
/// <summary> /// Validates the given instance. /// </summary> /// <param name="instance">The instance that should be validated.</param> /// <param name="attribute">The <see cref="ValidationAttribute"/> that should be handled.</param> /// <param name="descriptor">A <see cref="PropertyDescriptor"/> instance for the property that is being validated.</param> /// <returns>An <see cref="IEnumerable{T}"/> of <see cref="ModelValidationRule"/> instances.</returns> public virtual IEnumerable<ModelValidationError> Validate(object instance, ValidationAttribute attribute, PropertyDescriptor descriptor) { var context = new ValidationContext(instance, null, null) { MemberName = descriptor == null ? null : descriptor.Name }; if(descriptor != null) { instance = descriptor.GetValue(instance); } var result = attribute.GetValidationResult(instance, context); if (result != null) { yield return new ModelValidationError(result.MemberNames, string.Join(" ", result.MemberNames.Select(attribute.FormatErrorMessage))); } }
/// <summary> /// Populates the error message from the given metadata. /// </summary> /// <param name="validationAttribute"></param> public void PopulateErrorMessage(ValidationAttribute validationAttribute) { Invariant.IsNotNull(this, "validationMetadata"); string errorMessage = null; if (ErrorMessage != null) { errorMessage = ErrorMessage(); } if (!String.IsNullOrEmpty(errorMessage)) { validationAttribute.ErrorMessage = errorMessage; } else if ((ErrorMessageResourceType != null) && (!String.IsNullOrEmpty(ErrorMessageResourceName))) { validationAttribute.ErrorMessageResourceType = ErrorMessageResourceType; validationAttribute.ErrorMessageResourceName = ErrorMessageResourceName; } }
/// <summary> /// Tests whether a value is valid against a single <see cref="ValidationAttribute" /> using the /// <see cref="ValidationContext" />. /// </summary> /// <param name="value">The value to be tested for validity.</param> /// <param name="validationContext">Describes the property member to validate.</param> /// <param name="attribute">The validation attribute to test.</param> /// <param name="validationError"> /// The validation error that occurs during validation. Will be <c>null</c> when the return /// value is <c>true</c>. /// </param> /// <returns><c>true</c> if the value is valid.</returns> /// <exception cref="ArgumentNullException">When <paramref name="validationContext" /> is null.</exception> private static bool TryValidate(object?value, ValidationContext validationContext, ValidationAttribute attribute, [NotNullWhen(false)] out ValidationError?validationError) { Debug.Assert(validationContext != null); var validationResult = attribute.GetValidationResult(value, validationContext); if (validationResult != ValidationResult.Success) { validationError = new ValidationError(attribute, value, validationResult !); return(false); } validationError = null; return(true); }
private static ValidationResult InvokeIsValid <TAttribute>(object validator, object?value, ValidationContext validationContext, ValidationAttribute validationAttribute) where TAttribute : ServiceValidationAttribute => ((IValidator <TAttribute>)validator).IsValid(value, validationContext, (TAttribute)validationAttribute);
/// <summary> /// Constructor that accepts a structured <see cref="ValidationResult" /> describing the problem. /// </summary> /// <param name="validationResult">The value describing the validation error</param> /// <param name="validatingAttribute">The attribute that triggered this exception</param> /// <param name="value">The value that caused the validating attribute to trigger the exception</param> public ValidationException(ValidationResult validationResult, ValidationAttribute validatingAttribute, object value) : this(validationResult.ErrorMessage, validatingAttribute, value) { _validationResult = validationResult; }
/// <summary> /// Constructor that accepts an error message, the failing attribute, and the invalid value. /// </summary> /// <param name="errorMessage">The localized error message</param> /// <param name="validatingAttribute">The attribute that triggered this exception</param> /// <param name="value">The value that caused the validating attribute to trigger the exception</param> public ValidationException(string errorMessage, ValidationAttribute validatingAttribute, object value) : base(errorMessage) { Value = value; ValidationAttribute = validatingAttribute; }
public static string GetDefaultErrorMessage(this ValidationAttribute attribute) => attribute switch {
private bool IsRequiredWithInsertExpression(PropertyInfo prop, System.ComponentModel.DataAnnotations.ValidationAttribute attr) { // required properties with an insert expression should not be validated as a regular required field return(prop.HasAttribute <InsertExpressionAttribute>() && attr.GetType().Equals(typeof(RequiredAttribute))); }
/// <summary> /// Constructor that accepts a structured <see cref="ValidationResult" /> describing the problem. /// </summary> /// <param name="validationResult">The value describing the validation error</param> /// <param name="validatingAttribute">The attribute that triggered this exception</param> /// <param name="value">The value that caused the validating attribute to trigger the exception</param> public extern ValidationException(ValidationResult validationResult, ValidationAttribute validatingAttribute, object value);
internal ValidationError(ValidationAttribute validationAttribute, object value, ValidationResult validationResult) { this.ValidationAttribute = validationAttribute; this.ValidationResult = validationResult; this.Value = value; }
private ExtendedValidationResult(ValidationAttribute validationAttribute, string errorMessage, IEnumerable <string>?memberNames = null) : base(errorMessage, memberNames) { ValidationAttribute = validationAttribute; }
public ValidationException(ValidationResult validationResult, ValidationAttribute validatingAttribute, object value) : this(validationResult != null ? validationResult.ErrorMessage : null, validatingAttribute, value) { this.ValidationResult = validationResult; }
/// <summary> /// Tests whether a value is valid against a single <see cref="ValidationAttribute" /> using the /// <see cref="ValidationContext" />. /// </summary> /// <param name="value">The value to be tested for validity.</param> /// <param name="validationContext">Describes the property member to validate.</param> /// <param name="attribute">The validation attribute to test.</param> /// <param name="validationError"> /// The validation error that occurs during validation. Will be <c>null</c> when the return /// value is <c>true</c>. /// </param> /// <returns><c>true</c> if the value is valid.</returns> /// <exception cref="ArgumentNullException">When <paramref name="validationContext" /> is null.</exception> private static bool TryValidate(object value, ValidationContext validationContext, ValidationAttribute attribute, out ValidationError validationError) { if (validationContext == null) { throw new ArgumentNullException("validationContext"); } var validationResult = attribute.GetValidationResult(value, validationContext); if (validationResult != ValidationResult.Success) { validationError = new ValidationError(attribute, value, validationResult); return(false); } validationError = null; return(true); }
public ValidationException(string errorMessage, ValidationAttribute validatingAttribute, object value) { throw new NotImplementedException(); }
public DataAnnotationsValidationRuleClass(DataAnnotations.ValidationAttribute validationAttribute) { _validationAttribute = validationAttribute; }
/// <summary> /// Constructor that accepts an error message, the failing attribute, and the invalid value. /// </summary> /// <param name="errorMessage">The localized error message</param> /// <param name="validatingAttribute">The attribute that triggered this exception</param> /// <param name="value">The value that caused the validating attribute to trigger the exception</param> public extern ValidationException(string errorMessage, ValidationAttribute validatingAttribute, object value);
public DataAnnotationsValidationRule(IPropertyDescriptor property, DataAnnotations.ValidationAttribute validationAttribute) : base(property) { _validationAttribute = validationAttribute; }