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>()); }
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)); }