public IEnumerable<ModelValidationResult> Validate(ModelValidationContext validationContext)
        {
            var metadata = validationContext.ModelMetadata;
            var memberName = metadata.PropertyName ?? metadata.ModelType.Name;
            var containerMetadata = validationContext.ContainerMetadata;
            var container = containerMetadata != null ? containerMetadata.Model : null;
            var context = new ValidationContext(container ?? metadata.Model)
            {
                DisplayName = metadata.GetDisplayName(),
                MemberName = memberName
            };

            var result = Attribute.GetValidationResult(metadata.Model, context);
            if (result != ValidationResult.Success)
            {
                // ModelValidationResult.MemberName is used by invoking validators (such as ModelValidator) to
                // construct the ModelKey for ModelStateDictionary. When validating at type level we want to append
                // the returned MemberNames if specified (e.g. person.Address.FirstName). For property validation, the
                // ModelKey can be constructed using the ModelMetadata and we should ignore MemberName (we don't want
                // (person.Name.Name). However the invoking validator does not have a way to distinguish between these
                // two cases. Consequently we'll only set MemberName if this validation returns a MemberName that is 
                // different from the property being validated.

                var errorMemberName = result.MemberNames.FirstOrDefault();
                if (string.Equals(errorMemberName, memberName, StringComparison.Ordinal))
                {
                    errorMemberName = null;
                }

                var validationResult = new ModelValidationResult(errorMemberName, result.ErrorMessage);
                return new ModelValidationResult[] { validationResult };
            }

            return Enumerable.Empty<ModelValidationResult>();
        }
        public void ValidateReturnsMemberNameIfItIsDifferentFromDisplayName()
        {
            // Arrange
            var metadata  = _metadataProvider.GetMetadataForType(() => new SampleModel(), typeof(SampleModel));
            var attribute = new Mock <ValidationAttribute> {
                CallBase = true
            };

            attribute.Protected()
            .Setup <ValidationResult>("IsValid", ItExpr.IsAny <object>(), ItExpr.IsAny <ValidationContext>())
            .Returns(new ValidationResult("Name error", new[] { "Name" }));
            var validator         = new DataAnnotationsModelValidator(attribute.Object);
            var validationContext = CreateValidationContext(metadata);

            // Act
            var results = validator.Validate(validationContext);

            // Assert
            ModelValidationResult validationResult = Assert.Single(results);

            Assert.Equal("Name", validationResult.MemberName);
        }
        public void ValidateReturnsSingleValidationResultIfOneMemberNameIsSpecified()
        {
            // Arrange
            const string errorMessage = "A different error message";
            var          metadata     = _metadataProvider.GetMetadataForType(() => new object(), typeof(object));
            var          attribute    = new Mock <ValidationAttribute> {
                CallBase = true
            };

            attribute.Protected()
            .Setup <ValidationResult>("IsValid", ItExpr.IsAny <object>(), ItExpr.IsAny <ValidationContext>())
            .Returns(new ValidationResult(errorMessage, new[] { "FirstName" }));
            var validator         = new DataAnnotationsModelValidator(attribute.Object);
            var validationContext = CreateValidationContext(metadata);

            // Act
            var results = validator.Validate(validationContext);

            // Assert
            ModelValidationResult validationResult = Assert.Single(results);

            Assert.Equal(errorMessage, validationResult.Message);
            Assert.Equal("FirstName", validationResult.MemberName);
        }
        public void ValidateReturnsSingleValidationResultIfMemberNameSequenceIsEmpty()
        {
            // Arrange
            const string errorMessage = "Some error message";
            var          metadata     = _metadataProvider.GetMetadataForProperty(() => 15, typeof(string), "Length");
            var          attribute    = new Mock <ValidationAttribute> {
                CallBase = true
            };

            attribute.Protected()
            .Setup <ValidationResult>("IsValid", ItExpr.IsAny <object>(), ItExpr.IsAny <ValidationContext>())
            .Returns(new ValidationResult(errorMessage, memberNames: null));
            var validator         = new DataAnnotationsModelValidator(attribute.Object);
            var validationContext = CreateValidationContext(metadata);

            // Act
            var results = validator.Validate(validationContext);

            // Assert
            ModelValidationResult validationResult = Assert.Single(results);

            Assert.Equal(errorMessage, validationResult.Message);
            Assert.Empty(validationResult.MemberName);
        }
        public IEnumerable <ModelValidationResult> Validate(ModelValidationContext validationContext)
        {
            var metadata          = validationContext.ModelMetadata;
            var memberName        = metadata.PropertyName ?? metadata.ModelType.Name;
            var containerMetadata = validationContext.ContainerMetadata;
            var container         = containerMetadata != null ? containerMetadata.Model : null;
            var context           = new ValidationContext(container ?? metadata.Model)
            {
                DisplayName = metadata.GetDisplayName(),
                MemberName  = memberName
            };

            var result = Attribute.GetValidationResult(metadata.Model, context);

            if (result != ValidationResult.Success)
            {
                // ModelValidationResult.MemberName is used by invoking validators (such as ModelValidator) to
                // construct the ModelKey for ModelStateDictionary. When validating at type level we want to append
                // the returned MemberNames if specified (e.g. person.Address.FirstName). For property validation, the
                // ModelKey can be constructed using the ModelMetadata and we should ignore MemberName (we don't want
                // (person.Name.Name). However the invoking validator does not have a way to distinguish between these
                // two cases. Consequently we'll only set MemberName if this validation returns a MemberName that is
                // different from the property being validated.

                var errorMemberName = result.MemberNames.FirstOrDefault();
                if (string.Equals(errorMemberName, memberName, StringComparison.Ordinal))
                {
                    errorMemberName = null;
                }

                var validationResult = new ModelValidationResult(errorMemberName, result.ErrorMessage);
                return(new ModelValidationResult[] { validationResult });
            }

            return(Enumerable.Empty <ModelValidationResult>());
        }
Beispiel #6
0
 private static ModelValidationResult CreateSubPropertyResult(ModelMetadata propertyMetadata,
                                                              ModelValidationResult propertyResult)
 {
     return new ModelValidationResult(propertyMetadata.PropertyName + '.' + propertyResult.MemberName,
                                      propertyResult.Message);
 }
 private static ModelValidationResult CreateSubPropertyResult(ModelMetadata propertyMetadata,
                                                              ModelValidationResult propertyResult)
 {
     return(new ModelValidationResult(propertyMetadata.PropertyName + '.' + propertyResult.MemberName,
                                      propertyResult.Message));
 }