/// <summary> /// Validates a property or an entity. /// </summary> /// <param name="entityValidationContext"> Validation context. Never null. </param> /// <param name="property"> Property to validate. Null for entity validation. Not null for property validation. </param> /// <returns> /// Validation errors as <see cref="IEnumerable{EntityValidationError}" /> . Empty if no errors, never null. /// </returns> public virtual IEnumerable <EntityValidationError> Validate( EntityValidationContext entityValidationContext, InternalValidateProperty property) { DebugCheck.NotNull(entityValidationContext); var validationContext = entityValidationContext.ExternalValidationContext; //validationContext.SetDisplayName(property, _displayAttribute); var objectToValidate = property == null ? entityValidationContext.InternalEntity.EntityValue : property.PropertyValue; ValidationResult validationResult = null; try { validationResult = _validationAttribute.GetValidationResult(objectToValidate, validationContext); } catch (Exception ex) { //throw new DbUnexpectedValidationException( // Strings.DbUnexpectedValidationException_ValidationAttribute( // validationContext.DisplayName, _validationAttribute.GetType()), // ex); throw new DbUnexpectedValidationException( ex.Message); } return(validationResult != ValidationResult.Success ? this.SplitValidationResults(validationContext.MemberName, new[] { validationResult }) : Enumerable.Empty <EntityValidationError>()); }
public virtual PropertyValidator GetPropertyValidator( InternalValidateEntity owningEntity, InternalValidateProperty property) { DebugCheck.NotNull(owningEntity); DebugCheck.NotNull(property); var entityValidator = GetEntityValidator(owningEntity); return(entityValidator != null?GetValidatorForProperty(entityValidator, property) : null); }
/// <summary> /// Validates a property. /// </summary> /// <param name="entityValidationContext"> Validation context. Never null. </param> /// <param name="property"> Property to validate. Never null. </param> /// <returns> /// Validation errors as <see cref="IEnumerable{EntityValidationError}" /> . Empty if no errors. Never null. /// </returns> public virtual IEnumerable <EntityValidationError> Validate( EntityValidationContext entityValidationContext, InternalValidateProperty property) { DebugCheck.NotNull(entityValidationContext); DebugCheck.NotNull(property); var validationErrors = new List <EntityValidationError>(); foreach (var validator in _propertyValidators) { validationErrors.AddRange(validator.Validate(entityValidationContext, property)); } return(validationErrors); }
/// <summary> /// Validates type properties. Any validation errors will be added to <paramref name="validationErrors" /> /// collection. /// </summary> /// <param name="entityValidationContext"> Validation context. Must not be null. </param> /// <param name="parentProperty"> The entry for the complex property. Null if validating an entity. </param> /// <param name="validationErrors"> Collection of validation errors. Any validation errors will be added to it. </param> /// <remarks> /// Note that <paramref name="validationErrors" /> will be modified by this method. Errors should be only added, /// never removed or changed. Taking a collection as a modifiable parameter saves a couple of memory allocations /// and a merge of validation error lists per entity. /// </remarks> protected override void ValidateProperties( EntityValidationContext entityValidationContext, InternalValidateProperty parentProperty, List <EntityValidationError> validationErrors) { DebugCheck.NotNull(entityValidationContext); DebugCheck.NotNull(validationErrors); var entityEntry = entityValidationContext.InternalEntity; foreach (var validator in PropertyValidators) { validationErrors.AddRange( validator.Validate(entityValidationContext, entityEntry.GetProperty(validator.PropertyName))); } }
/// <summary> /// Validates type properties. Any validation errors will be added to <paramref name="validationErrors" /> /// collection. /// </summary> /// <param name="entityValidationContext"> Validation context. Must not be null. </param> /// <param name="parentProperty"> The entry for the complex property. Null if validating an entity. </param> /// <param name="validationErrors"> Collection of validation errors. Any validation errors will be added to it. </param> /// <remarks> /// Note that <paramref name="validationErrors" /> will be modified by this method. Errors should be only added, /// never removed or changed. Taking a collection as a modifiable parameter saves a couple of memory allocations /// and a merge of validation error lists per entity. /// </remarks> protected override void ValidateProperties( EntityValidationContext entityValidationContext, InternalValidateProperty parentProperty, List <EntityValidationError> validationErrors) { DebugCheck.NotNull(entityValidationContext); DebugCheck.NotNull(parentProperty); DebugCheck.NotNull(validationErrors); //Debug.Assert(parentProperty.EntryMetadata.IsComplex, "A complex type expected."); Debug.Assert(parentProperty.PropertyValue != null); //foreach (var validator in PropertyValidators) //{ // var complexProperty = parentProperty.Property(validator.PropertyName); // validationErrors.AddRange(validator.Validate(entityValidationContext, complexProperty)); //} }
/// <summary> /// Validates an instance. /// </summary> /// <param name="entityValidationContext"> Entity validation context. Must not be null. </param> /// <param name="property"> The entry for the complex property. Null if validating an entity. </param> /// <returns> /// <see cref="DbEntityValidationResult" /> instance. Never null. /// </returns> /// <remarks> /// Protected so it doesn't appear on EntityValidator. /// </remarks> protected IEnumerable <EntityValidationError> Validate( EntityValidationContext entityValidationContext, InternalValidateProperty property) { var validationErrors = new List <EntityValidationError>(); ValidateProperties(entityValidationContext, property, validationErrors); // only run type level validation if all properties were validated successfully if (!validationErrors.Any()) { foreach (var typeLevelValidator in _typeLevelValidators) { validationErrors.AddRange(typeLevelValidator.Validate(entityValidationContext, property)); } } return(validationErrors); }
/// <summary> /// Validates an entity or a complex type implementing IValidatableObject interface. /// This method is virtual to allow mocking. /// </summary> /// <param name="entityValidationContext"> Validation context. Never null. </param> /// <param name="property"> Property to validate. Null if this is the entity that will be validated. Never null if this is the complex type that will be validated. </param> /// <returns> /// Validation error as <see cref="IEnumerable{EntityValidationError}" /> . Empty if no errors. Never null. /// </returns> /// <remarks> /// Note that <paramref name="property" /> is used to figure out what needs to be validated. If it not null the complex /// type will be validated otherwise the entity will be validated. /// Also if this is an IValidatableObject complex type but the instance (.CurrentValue) is null we won't validate /// anything and will not return any errors. The reason for this is that Validation is supposed to validate using /// information the user provided and not some additional implicit rules. (ObjectContext will throw for operations /// that involve null complex properties). /// </remarks> public virtual IEnumerable <EntityValidationError> Validate( EntityValidationContext entityValidationContext, InternalValidateProperty property) { DebugCheck.NotNull(entityValidationContext); Debug.Assert( (property == null && entityValidationContext.InternalEntity.EntityValue is IValidatableObject) || (property != null && (property.PropertyValue == null || property.PropertyValue is IValidatableObject)), "Neither entity nor complex type implements IValidatableObject."); if (property != null && property.PropertyValue == null) { return(Enumerable.Empty <EntityValidationError>()); } var validationContext = entityValidationContext.ExternalValidationContext; //validationContext.SetDisplayName(property, _displayAttribute); var validatableObject = (IValidatableObject)(property == null ? entityValidationContext.InternalEntity.EntityValue : property.PropertyValue); IEnumerable <ValidationResult> validationResults = null; try { validationResults = validatableObject.Validate(validationContext); } catch (Exception ex) { //throw new DbUnexpectedValidationException( // Strings.DbUnexpectedValidationException_IValidatableObject( // validationContext.DisplayName, ObjectContextTypeCache.GetObjectType(validatableObject.GetType())), // ex); throw new DbUnexpectedValidationException( ex.Message); } return(this.SplitValidationResults( validationContext.MemberName, validationResults ?? Enumerable.Empty <ValidationResult>())); }
/// <summary> /// Validates a complex property. /// </summary> /// <param name="entityValidationContext"> Validation context. Never null. </param> /// <param name="property"> Property to validate. Never null. </param> /// <returns> /// Validation errors as <see cref="IEnumerable{EntityValidationError}" /> . Empty if no errors. Never null. /// </returns> public override IEnumerable <EntityValidationError> Validate( EntityValidationContext entityValidationContext, InternalValidateProperty property) { DebugCheck.NotNull(property); var validationErrors = new List <EntityValidationError>(); validationErrors.AddRange(base.Validate(entityValidationContext, property)); // don't drill into complex types if there were errors or the complex property has not been initialized at all if (!validationErrors.Any() && property.PropertyValue != null && _complexTypeValidator != null) { validationErrors.AddRange( _complexTypeValidator.Validate(entityValidationContext, property)); } return(validationErrors); }
/// <summary> /// Gets a validator for the <paramref name="memberEntry" />. /// </summary> /// <param name="entityValidator"> Entity validator. </param> /// <param name="memberEntry"> Property to get a validator for. </param> /// <returns> /// Validator to validate <paramref name="memberEntry" /> . Possibly null if there is no validation for the /// <paramref /// name="memberEntry" /> /// . /// </returns> /// <remarks> /// For complex properties this method walks up the type hierarchy to get to the entity level and then goes down /// and gets a validator for the child property that is an ancestor of the property to validate. If a validator /// returned for an ancestor is null it means that there is no validation defined beneath and the method just /// propagates (and eventually returns) null. /// </remarks> protected virtual PropertyValidator GetValidatorForProperty( EntityValidator entityValidator, InternalValidateProperty memberEntry) { var complexPropertyEntry = memberEntry; if (complexPropertyEntry == null) { //var propertyValidator = // GetValidatorForProperty(entityValidator, complexPropertyEntry.ParentPropertyEntry) as // ComplexPropertyValidator; //// if a validator for parent property is null there is no validation for child properties. //// just propagate the null. //return propertyValidator != null && propertyValidator.ComplexTypeValidator != null // ? propertyValidator.ComplexTypeValidator.GetPropertyValidator(memberEntry.Name) // : null; return(null); } else { return(entityValidator.GetPropertyValidator(memberEntry.PropertyName)); } }
/// <summary> /// Validates an instance. /// </summary> /// <param name="entityValidationContext"> Entity validation context. Must not be null. </param> /// <param name="property"> The entry for the complex property. Null if validating an entity. </param> /// <returns> /// <see cref="DbEntityValidationResult" /> instance. Never null. /// </returns> public new IEnumerable <EntityValidationError> Validate( EntityValidationContext entityValidationContext, InternalValidateProperty property) { return(base.Validate(entityValidationContext, property)); }
/// <summary> /// Validates type properties. Any validation errors will be added to <paramref name="validationErrors" /> /// collection. /// </summary> /// <param name="entityValidationContext"> Validation context. Must not be null. </param> /// <param name="parentProperty"> The entry for the complex property. Null if validating an entity. </param> /// <param name="validationErrors"> Collection of validation errors. Any validation errors will be added to it. </param> /// <remarks> /// Note that <paramref name="validationErrors" /> will be modified by this method. Errors should be only added, /// never removed or changed. Taking a collection as a modifiable parameter saves a couple of memory allocations /// and a merge of validation error lists per entity. /// </remarks> protected abstract void ValidateProperties( EntityValidationContext entityValidationContext, InternalValidateProperty parentProperty, List <EntityValidationError> validationErrors);