상속: System.Web.Mvc.CompareAttribute
예제 #1
0
        public static void Constructor(string otherProperty)
        {
            CompareAttribute attribute = new CompareAttribute(otherProperty);
            Assert.Equal(otherProperty, attribute.OtherProperty);

            Assert.True(attribute.RequiresValidationContext);
        }
예제 #2
0
        public static void Validate_PropertyHasDisplayName_UpdatesFormatErrorMessageToContainDisplayName()
        {
            CompareAttribute attribute = new CompareAttribute(nameof(CompareObject.ComparePropertyWithDisplayName));

            string oldErrorMessage = attribute.FormatErrorMessage("name");
            Assert.False(oldErrorMessage.Contains("CustomDisplayName"));

            Assert.Throws<ValidationException>(() => attribute.Validate("test1", new ValidationContext(new CompareObject("test"))));

            string newErrorMessage = attribute.FormatErrorMessage("name");
            Assert.NotEqual(oldErrorMessage, newErrorMessage);
            Assert.True(newErrorMessage.Contains("CustomDisplayName"));
        }
예제 #3
0
        public static void Validate_PropertyHasDisplayName_UpdatesFormatErrorMessageToContainDisplayName()
        {
            CompareAttribute attribute = new CompareAttribute(nameof(CompareObject.ComparePropertyWithDisplayName));

            string oldErrorMessage = attribute.FormatErrorMessage("name");

            Assert.DoesNotContain("CustomDisplayName", oldErrorMessage);

            Assert.Throws <ValidationException>(() => attribute.Validate("test1", new ValidationContext(new CompareObject("test"))));

            string newErrorMessage = attribute.FormatErrorMessage("name");

            Assert.NotEqual(oldErrorMessage, newErrorMessage);
            Assert.Contains("CustomDisplayName", newErrorMessage);
        }
 /// <summary>
 /// Map rules for the default attributes.
 /// </summary>
 protected virtual void MapDefaultRules()
 {
     AddDelegateRule <RangeAttribute>((attribute, errMsg) =>
     {
         var attr = (RangeAttribute)attribute;
         return(new[]
         {
             new ModelClientValidationRangeRule(errMsg,
                                                attr.Minimum,
                                                attr.Maximum)
         });
     });
     AddDelegateRule <RegularExpressionAttribute>((attribute, errMsg) =>
     {
         var attr = (RegularExpressionAttribute)attribute;
         return(new[]
         {
             new ModelClientValidationRegexRule(
                 errMsg, attr.Pattern)
         });
     });
     AddDelegateRule <RequiredAttribute>((attribute, errMsg) =>
     {
         var attr = (RequiredAttribute)attribute;
         return(new[]
         {
             new ModelClientValidationRequiredRule(errMsg)
         });
     });
     AddDelegateRule <StringLengthAttribute>((attribute, errMsg) =>
     {
         var attr = (StringLengthAttribute)attribute;
         return(new[]
         {
             new ModelClientValidationStringLengthRule(
                 errMsg, attr.MinimumLength,
                 attr.MaximumLength)
         });
     });
     AddDelegateRule <CompareAttribute>((attribute, errMsg) =>
     {
         var attr = (CompareAttribute)attribute;
         return(new[]
         {
             new ModelClientValidationEqualToRule(errMsg, CompareAttribute.FormatPropertyForClientValidation(attr.OtherProperty))
         });
     });
 }
예제 #5
0
        public void ValidateThrowsWhenPropertyNameIsUnknown()
        {
            CompareObject currentObject = new CompareObject("a");
            object        otherObject   = new CompareObject("b");

            ValidationContext testContext = new ValidationContext(otherObject, null, null);

            testContext.DisplayName = "CurrentProperty";

            CompareAttribute attr = new CompareAttribute("UnknownPropertyName");

            Assert.Throws <ValidationException>(
                () => attr.Validate(currentObject.CompareProperty, testContext),
                "Could not find a property named UnknownPropertyName."
                );
        }
예제 #6
0
        public void ValidateThrowsWhenComparedObjectsAreNotEqual()
        {
            CompareObject currentObject = new CompareObject("a");
            object        otherObject   = new CompareObject("b");

            ValidationContext testContext = new ValidationContext(otherObject, null, null);

            testContext.DisplayName = "CurrentProperty";

            CompareAttribute attr = new CompareAttribute("CompareProperty");

            ExceptionHelper.ExpectException <System.ComponentModel.DataAnnotations.ValidationException>(
                delegate {
                attr.Validate(currentObject.CompareProperty, testContext);
            }, "'CurrentProperty' and 'CompareProperty' do not match.");
        }
예제 #7
0
        public void ValidateUsesSetDisplayName()
        {
            CompareObject currentObject = new CompareObject("a");
            object        otherObject   = new CompareObject("b");

            ValidationContext testContext = new ValidationContext(otherObject, null, null);

            testContext.DisplayName = "CurrentProperty";

            CompareAttribute attr = new CompareAttribute("ComparePropertyWithDisplayName");

            attr.OtherPropertyDisplayName = "SetDisplayName";

            Assert.Throws <ValidationException>(
                delegate { attr.Validate(currentObject.CompareProperty, testContext); }, "'CurrentProperty' and 'SetDisplayName' do not match.");
        }
예제 #8
0
        public void ValidateThrowsWhenPropertyNameIsUnknown()
        {
            CompareObject currentObject = new CompareObject("a");
            object        otherObject   = new CompareObject("b");

            ValidationContext testContext = new ValidationContext(otherObject, null, null);

            testContext.DisplayName = "CurrentProperty";

            CompareAttribute attr = new CompareAttribute("UnknownPropertyName");

            ExceptionHelper.ExpectException <System.ComponentModel.DataAnnotations.ValidationException>(
                () => attr.Validate(currentObject.CompareProperty, testContext),
                "Could not find a property named UnknownPropertyName."
                );
        }
예제 #9
0
        //    System.ComponentModel.DataAnnotations.ValidationAttribute
        //      System.ComponentModel.DataAnnotations.CompareAttribute
        //      System.ComponentModel.DataAnnotations.CustomValidationAttribute
        //      System.ComponentModel.DataAnnotations.DataTypeAttribute
        //        System.ComponentModel.DataAnnotations.CreditCardAttribute
        //        System.ComponentModel.DataAnnotations.EmailAddressAttribute
        //        System.ComponentModel.DataAnnotations.EnumDataTypeAttribute
        //        System.ComponentModel.DataAnnotations.FileExtensionsAttribute
        //        System.ComponentModel.DataAnnotations.PhoneAttribute
        //        System.ComponentModel.DataAnnotations.UrlAttribute
        //      System.ComponentModel.DataAnnotations.MaxLengthAttribute
        //      System.ComponentModel.DataAnnotations.MinLengthAttribute
        //      System.ComponentModel.DataAnnotations.RangeAttribute
        //      System.ComponentModel.DataAnnotations.RegularExpressionAttribute
        //      System.ComponentModel.DataAnnotations.RequiredAttribute
        //      System.ComponentModel.DataAnnotations.StringLengthAttribute

        //
        public static CompareAttribute CreateCompareAttribute(this XElement annotation)
        {
            const string NAME = "Compare";
            string       name = annotation.Attribute(SchemaVocab.Name).Value;

            if (name != NAME)
            {
                throw new ArgumentException(string.Format(SchemaMessages.ExpectedBut, NAME, name));
            }

            string           value     = annotation.GetArgumentValue("OtherProperty");
            CompareAttribute attribute = new CompareAttribute(value);

            FillValidationAttribute(attribute, annotation);
            return(attribute);
        }
예제 #10
0
 public CompareAttributeWrapper(CompareAttribute attribute)
     : base(attribute.OtherProperty)
 {
     // Copy settable properties from wrapped attribute. Don't reset default message accessor (set as
     // CompareAttribute constructor calls ValidationAttribute constructor) when all properties are null to
     // preserve default error message. Reset the message accessor when just ErrorMessageResourceType is
     // non-null to ensure correct InvalidOperationException.
     if (!string.IsNullOrEmpty(attribute.ErrorMessage) ||
         !string.IsNullOrEmpty(attribute.ErrorMessageResourceName) ||
         attribute.ErrorMessageResourceType != null)
     {
         ErrorMessage             = attribute.ErrorMessage;
         ErrorMessageResourceName = attribute.ErrorMessageResourceName;
         ErrorMessageResourceType = attribute.ErrorMessageResourceType;
     }
 }
예제 #11
0
        public void ModelClientValidationEqualToRuleUsesSetDisplayName()
        {
            Mock <ModelMetadataProvider> provider = new Mock <ModelMetadataProvider>();
            ModelMetadata metadata = new ModelMetadata(provider.Object, typeof(CompareObject), null, typeof(string), null);

            metadata.DisplayName = "CurrentProperty";

            CompareAttribute attr = new CompareAttribute("ComparePropertyWithDisplayName");

            attr.OtherPropertyDisplayName = "SetDisplayName";

            List <ModelClientValidationRule> ruleList   = new List <ModelClientValidationRule>(attr.GetClientValidationRules(metadata, null));
            ModelClientValidationRule        rule       = Assert.Single(ruleList);
            ModelClientValidationEqualToRule actualRule = Assert.IsType <ModelClientValidationEqualToRule>(rule);

            Assert.Equal("'CurrentProperty' and 'SetDisplayName' do not match.", actualRule.ErrorMessage);
        }
예제 #12
0
        public void GetClientValidationRulesReturnsModelClientValidationEqualToRule()
        {
            Mock <ModelMetadataProvider> provider = new Mock <ModelMetadataProvider>();
            Mock <ModelMetadata>         metadata = new Mock <ModelMetadata>(provider.Object, null, null, typeof(string), null);

            metadata.Setup(m => m.DisplayName).Returns("CurrentProperty");

            CompareAttribute attr = new CompareAttribute("CompareProperty");
            List <ModelClientValidationRule> ruleList = new List <ModelClientValidationRule>(attr.GetClientValidationRules(metadata.Object, null));

            ModelClientValidationRule        rule       = Assert.Single(ruleList);
            ModelClientValidationEqualToRule actualRule = Assert.IsType <ModelClientValidationEqualToRule>(rule);

            Assert.Equal("'CurrentProperty' and 'CompareProperty' do not match.", actualRule.ErrorMessage);
            Assert.Equal("equalto", actualRule.ValidationType);
            Assert.Equal("*.CompareProperty", actualRule.ValidationParameters["other"]);
        }
예제 #13
0
        public void ClientRulesWithCompareAttribute_ErrorMessageUsesPropertyName()
        {
            // Arrange
            var metadataProvider = new DataAnnotationsModelMetadataProvider();
            var metadata         = metadataProvider.GetMetadataForProperty(() => null, typeof(PropertyNameModel), "MyProperty");
            var attribute        = new CompareAttribute("OtherProperty");
            var context          = new ClientModelValidationContext(metadata, metadataProvider);
            var adapter          = new CompareAttributeAdapter(attribute);

            // Act
            var rules = adapter.GetClientValidationRules(context);

            // Assert
            var rule = Assert.Single(rules);

            Assert.Equal("'MyProperty' and 'OtherProperty' do not match.", rule.ErrorMessage);
        }
        public void AddValidation_adds_confirmed_rule()
        {
            // Arrange
            var attribute = new CompareAttribute("PropertyName");
            var adapter   = new CompareAttributeAdapter(attribute);

            var context = new ClientModelValidationContextBuilder()
                          .WithModelType <string>()
                          .Build();

            // Act
            adapter.AddValidation(context);

            // Assert
            context.Attributes.Keys.ShouldContain("v-validate");
            context.Attributes["v-validate"].ShouldBe("{confirmed:'PropertyName'}");
        }
        /// <summary>
        /// When implemented in a derived class, returns metadata for client validation.
        /// </summary>
        /// <returns>
        /// The metadata for client validation.
        /// </returns>
        public override IEnumerable <ModelClientValidationRule> GetClientValidationRules()
        {
            ValidatorProperties validatorProperties       = ValidationRule.Validator.GetValidatorProperties();
            MemberInfo          memberToCompareMemberInfo = validatorProperties.GetPropertyValue <MemberInfo>(Constants.ValidationMessageParameterNames.MEMBER_TO_COMPARE_MEMBER_INFO);
            PropertyInfo        propertyInfoToCompare     = memberToCompareMemberInfo as PropertyInfo;

            if (propertyInfoToCompare != null)
            {
                string message   = ValidationRule.GetValidationMessage(Metadata.Model);
                Type   ownerType = validatorProperties.GetPropertyValue <Type>(Constants.ValidationMessageParameterNames.OWNER_TYPE);

                string validationModelPropertyName = propertyInfoToCompare.Name;
                string propertyName = GetTransformedPropertyName(validationModelPropertyName, ownerType) ?? validationModelPropertyName;

                string propertyForClientValidation = CompareAttribute.FormatPropertyForClientValidation(propertyName);
                yield return(new ModelClientValidationEqualToRule(message, propertyForClientValidation));
            }
        }
예제 #16
0
        public void ModelClientValidationEqualToRuleErrorMessageUsesOtherPropertyDisplayName()
        {
            Mock <ModelMetadataProvider> provider = new Mock <ModelMetadataProvider>();
            ModelMetadata metadata = new ModelMetadata(provider.Object, typeof(CompareObject), null, typeof(string), null);

            metadata.DisplayName = "CurrentProperty";

            CompareAttribute attr = new CompareAttribute("ComparePropertyWithDisplayName");
            List <ModelClientValidationRule> ruleList = new List <ModelClientValidationRule>(attr.GetClientValidationRules(metadata, null));

            Assert.Equal(ruleList.Count, 1);

            ModelClientValidationEqualToRule actualRule = ruleList[0] as ModelClientValidationEqualToRule;

            Assert.Equal("'CurrentProperty' and 'DisplayName' do not match.", actualRule.ErrorMessage);
            Assert.Equal("equalto", actualRule.ValidationType);
            Assert.Equal("*.ComparePropertyWithDisplayName", actualRule.ValidationParameters["other"]);
        }
예제 #17
0
        public void GuardClauses()
        {
            //Act & Assert
            Assert.ThrowsArgumentNull(
                delegate
            {
                new CompareAttribute(null);
            },
                "otherProperty"
                );

            Assert.ThrowsArgumentNullOrEmpty(
                delegate
            {
                CompareAttribute.FormatPropertyForClientValidation(null);
            },
                "property"
                );
        }
        public override IEnumerable <ModelClientValidationRule> GetClientValidationRules()
        {
            var propertyToCompare = EqualValidator.MemberToCompare as PropertyInfo;

            if (propertyToCompare != null)
            {
                // If propertyToCompare is not null then we're comparing to another property.
                // If propertyToCompare is null then we're either comparing against a literal value, a field or a method call.
                // We only care about property comparisons in this case.

                var formatter = new MessageFormatter()
                                .AppendPropertyName(Rule.PropertyDescription)
                                .AppendArgument("PropertyValue", propertyToCompare.Name);


                string message = formatter.BuildMessage(EqualValidator.ErrorMessageSource.GetString());
                yield return(new ModelClientValidationEqualToRule(message, CompareAttribute.FormatPropertyForClientValidation(propertyToCompare.Name)));
            }
        }
        public void ClientRulesWithCompareAttribute_ErrorMessageUsesPropertyName()
        {
            // Arrange
            var metadataProvider  = TestModelMetadataProvider.CreateDefaultProvider();
            var metadata          = metadataProvider.GetMetadataForProperty(typeof(PropertyNameModel), "MyProperty");
            var attribute         = new CompareAttribute("OtherProperty");
            var serviceCollection = new ServiceCollection();
            var requestServices   = serviceCollection.BuildServiceProvider();
            var context           = new ClientModelValidationContext(metadata, metadataProvider, requestServices);
            var adapter           = new CompareAttributeAdapter(attribute);

            // Act
            var rules = adapter.GetClientValidationRules(context);

            // Assert
            var rule = Assert.Single(rules);

            Assert.Equal("'MyProperty' and 'OtherProperty' do not match.", rule.ErrorMessage);
        }
    public override IEnumerable <ModelClientValidationRule> GetClientValidationRules()
    {
        if (!this.ShouldGenerateClientSideRules())
        {
            yield break;
        }
        var validator    = Validator as LessThanOrEqualValidator;
        var errorMessage = new MessageFormatter()
                           .AppendPropertyName(this.Rule.GetDisplayName())
                           .BuildMessage(validator.ErrorMessageSource.GetString());
        var rule = new ModelClientValidationRule
        {
            ErrorMessage   = errorMessage,
            ValidationType = "lessthanorequaldate"
        };

        rule.ValidationParameters["other"] = CompareAttribute.FormatPropertyForClientValidation(validator.MemberToCompare.Name);
        yield return(rule);
    }
예제 #21
0
    public void ClientRulesWithCompareAttribute_ErrorMessageUsesDisplayName()
    {
        // Arrange
        var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
        var metadata         = metadataProvider.GetMetadataForProperty(typeof(PropertyDisplayNameModel), "MyProperty");

        var attribute = new CompareAttribute("OtherProperty");

        attribute.ErrorMessage = "CompareAttributeErrorMessage";

        var stringLocalizer    = new Mock <IStringLocalizer>();
        var expectedProperties = new object[] { "MyPropertyDisplayName", "OtherPropertyDisplayName" };

        var expectedMessage = "'MyPropertyDisplayName' and 'OtherPropertyDisplayName' do not match.";

        stringLocalizer.Setup(s => s[attribute.ErrorMessage, expectedProperties])
        .Returns(new LocalizedString(attribute.ErrorMessage, expectedMessage));

        var adapter = new CompareAttributeAdapter(attribute, stringLocalizer: stringLocalizer.Object);

        var actionContext = new ActionContext();
        var context       = new ClientModelValidationContext(
            actionContext,
            metadata,
            metadataProvider,
            new Dictionary <string, string>());

        // Act
        adapter.AddValidation(context);

        // Assert
        Assert.Collection(
            context.Attributes,
            kvp => { Assert.Equal("data-val", kvp.Key); Assert.Equal("true", kvp.Value); },
            kvp => { Assert.Equal("data-val-equalto", kvp.Key); Assert.Equal(expectedMessage, kvp.Value); },
            kvp =>
        {
            Assert.Equal("data-val-equalto-other", kvp.Key);
            Assert.Equal("*.OtherProperty", kvp.Value);
        });
    }
예제 #22
0
        public void ClientRulesWithCompareAttribute_ErrorMessageUsesResourceOverride()
        {
            // Arrange
            var metadataProvider = new DataAnnotationsModelMetadataProvider();
            var metadata         = metadataProvider.GetMetadataForProperty(() => null, typeof(PropertyNameModel), "MyProperty");
            var attribute        = new CompareAttribute("OtherProperty")
            {
                ErrorMessageResourceName = "CompareAttributeTestResource",
                ErrorMessageResourceType = typeof(Test.Resources),
            };
            var context = new ClientModelValidationContext(metadata, metadataProvider);
            var adapter = new CompareAttributeAdapter(attribute);

            // Act
            var rules = adapter.GetClientValidationRules(context);

            // Assert
            var rule = Assert.Single(rules);

            Assert.Equal("Comparing MyProperty to OtherProperty.", rule.ErrorMessage);
        }
예제 #23
0
        public void ClientRulesWithCompareAttribute_ErrorMessageUsesOverride()
        {
            // Arrange
            var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var metadata         = metadataProvider.GetMetadataForProperty(typeof(PropertyNameModel), "MyProperty");
            var attribute        = new CompareAttribute("OtherProperty")
            {
                ErrorMessage = "Hello '{0}', goodbye '{1}'."
            };
            var serviceCollection = new ServiceCollection();
            var requestServices   = serviceCollection.BuildServiceProvider();
            var context           = new ClientModelValidationContext(metadata, metadataProvider, requestServices);
            var adapter           = new CompareAttributeAdapter(attribute, stringLocalizer: null);

            // Act
            var rules = adapter.GetClientValidationRules(context);

            // Assert
            var rule = Assert.Single(rules);

            Assert.Equal("Hello 'MyProperty', goodbye 'OtherProperty'.", rule.ErrorMessage);
        }
예제 #24
0
        public void GetValidationResult()
        {
            var sla = new CompareAttribute("B");
            var obj = new TestModel {
                A = "x", B = "x"
            };
            var ctx = new ValidationContext(obj, null, null);

            Assert.IsNotNull(sla.GetValidationResult(null, ctx), "#A1-1");
            Assert.IsNotNull(sla.GetValidationResult(String.Empty, ctx), "#A1-2");
            Assert.IsNotNull(sla.GetValidationResult(obj, ctx), "#A1-3");
            Assert.IsNull(sla.GetValidationResult(obj.A, ctx), "#A1-4");

            obj = new TestModel {
                A = "x", B = "n"
            };

            Assert.IsNotNull(sla.GetValidationResult(null, ctx), "#B-1");
            Assert.IsNotNull(sla.GetValidationResult(obj, ctx), "#B-2");
            Assert.IsNotNull(sla.GetValidationResult(true, ctx), "#B-3");
            Assert.IsNotNull(sla.GetValidationResult(DateTime.Now, ctx), "#B-4");
        }
예제 #25
0
            public static string GetOtherPropertyDisplayName(
                ModelValidationContextBase validationContext,
                CompareAttribute attribute)
            {
                // The System.ComponentModel.DataAnnotations.CompareAttribute doesn't populate the
                // OtherPropertyDisplayName until after IsValid() is called. Therefore, at the time we get
                // the error message for client validation, the display name is not populated and won't be used.
                var otherPropertyDisplayName = attribute.OtherPropertyDisplayName;

                if (otherPropertyDisplayName == null && validationContext.ModelMetadata.ContainerType != null)
                {
                    var otherProperty = validationContext.MetadataProvider.GetMetadataForProperty(
                        validationContext.ModelMetadata.ContainerType,
                        attribute.OtherProperty);
                    if (otherProperty != null)
                    {
                        return(otherProperty.GetDisplayName());
                    }
                }

                return(attribute.OtherProperty);
            }
예제 #26
0
        public void ClientRulesWithCompareAttribute_ErrorMessageUsesPropertyName()
        {
            // Arrange
            var metadataProvider  = TestModelMetadataProvider.CreateDefaultProvider();
            var metadata          = metadataProvider.GetMetadataForProperty(typeof(PropertyNameModel), "MyProperty");
            var attribute         = new CompareAttribute("OtherProperty");
            var serviceCollection = new ServiceCollection();
            var requestServices   = serviceCollection.BuildServiceProvider();
            var context           = new ClientModelValidationContext(metadata, metadataProvider, requestServices);
            var adapter           = new CompareAttributeAdapter(attribute, stringLocalizer: null);

            // Act
            var rules = adapter.GetClientValidationRules(context);

            // Assert
            var rule = Assert.Single(rules);

            // Mono issue - https://github.com/aspnet/External/issues/19
            Assert.Equal(
                PlatformNormalizer.NormalizeContent("'MyProperty' and 'OtherProperty' do not match."),
                rule.ErrorMessage);
        }
        public override IEnumerable <ModelClientValidationRule> GetClientValidationRules()
        {
            if (!ShouldGenerateClientSideRules())
            {
                yield break;
            }

            var propertyToCompare = EqualValidator.MemberToCompare as PropertyInfo;

            if (propertyToCompare != null)
            {
                // If propertyToCompare is not null then we're comparing to another property.
                // If propertyToCompare is null then we're either comparing against a literal value, a field or a method call.
                // We only care about property comparisons in this case.

                var comparisonDisplayName =
                    ValidatorOptions.DisplayNameResolver(Rule.TypeToValidate, propertyToCompare, null)
                    ?? propertyToCompare.Name.SplitPascalCase();

                var formatter = ValidatorOptions.MessageFormatterFactory()
                                .AppendPropertyName(Rule.GetDisplayName())
                                .AppendArgument("ComparisonValue", comparisonDisplayName);


                string message;
                try {
                    message = EqualValidator.Options.ErrorMessageSource.GetString(null);
                }
                catch (FluentValidationMessageFormatException) {
                    // User provided a message that contains placeholders based on object properties. We can't use that here, so just fall back to the default.
                    message = ValidatorOptions.LanguageManager.GetStringForValidator <EqualValidator>();
                }
                message = formatter.BuildMessage(message);
#pragma warning disable 618
                yield return(new ModelClientValidationEqualToRule(message, CompareAttribute.FormatPropertyForClientValidation(propertyToCompare.Name)));

#pragma warning restore 618
            }
        }
예제 #28
0
        public void ClientRulesWithCompareAttribute_ErrorMessageUsesResourceOverride()
        {
            // Arrange
            var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
            var metadata         = metadataProvider.GetMetadataForProperty(typeof(PropertyNameModel), "MyProperty");
            var attribute        = new CompareAttribute("OtherProperty")
            {
                ErrorMessageResourceName = "CompareAttributeTestResource",
                ErrorMessageResourceType = typeof(DataAnnotations.Test.Resources),
            };
            var serviceCollection = new ServiceCollection();
            var requestServices   = serviceCollection.BuildServiceProvider();
            var context           = new ClientModelValidationContext(metadata, metadataProvider, requestServices);
            var adapter           = new CompareAttributeAdapter(attribute, stringLocalizer: null);

            // Act
            var rules = adapter.GetClientValidationRules(context);

            // Assert
            var rule = Assert.Single(rules);

            Assert.Equal("Comparing MyProperty to OtherProperty.", rule.ErrorMessage);
        }
예제 #29
0
    public void ClientRulesWithCompareAttribute_ErrorMessageUsesResourceOverride()
    {
        // Arrange
        var metadataProvider = TestModelMetadataProvider.CreateDefaultProvider();
        var metadata         = metadataProvider.GetMetadataForProperty(typeof(PropertyNameModel), "MyProperty");

        var attribute = new CompareAttribute("OtherProperty")
        {
            ErrorMessageResourceName = "CompareAttributeTestResource",
            ErrorMessageResourceType = typeof(DataAnnotations.Test.Resources),
        };
        var adapter = new CompareAttributeAdapter(attribute, stringLocalizer: null);

        var expectedMessage = "Comparing MyProperty to OtherProperty.";

        var actionContext = new ActionContext();
        var context       = new ClientModelValidationContext(
            actionContext,
            metadata,
            metadataProvider,
            new Dictionary <string, string>());

        // Act
        adapter.AddValidation(context);

        // Assert
        Assert.Collection(
            context.Attributes,
            kvp => { Assert.Equal("data-val", kvp.Key); Assert.Equal("true", kvp.Value); },
            kvp => { Assert.Equal("data-val-equalto", kvp.Key); Assert.Equal(expectedMessage, kvp.Value); },
            kvp =>
        {
            Assert.Equal("data-val-equalto-other", kvp.Key);
            Assert.Equal("*.OtherProperty", kvp.Value);
        });
    }
        private static string WriteExtenders(PropertyInfo p, out bool isValidatable)
        {
            isValidatable = false;
            StringBuilder sb = new StringBuilder();

            sb.Append(".extend({ editState : false, disableValidation : false, empty : true })");

            RequiredAttribute requiredAttribute = p.GetCustomAttribute <RequiredAttribute>();

            if (requiredAttribute != null)
            {
                sb.Append($".extend({{ required: {{ message: \"{requiredAttribute.FormatErrorMessage(p.Name)}\", onlyIf: function() {{ return ko.utils.isPropertyValidatable(self, \"{ p.Name}\"); }} }} }})");
                isValidatable = true;
            }

            MinLengthAttribute minLengthAttribute = p.GetCustomAttribute <MinLengthAttribute>();

            if (minLengthAttribute != null)
            {
                sb.Append(string.Format(".extend({ minLength: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", minLengthAttribute.FormatErrorMessage(p.Name), minLengthAttribute.Length, p.Name));
                isValidatable = true;
            }

            MaxLengthAttribute maxLengthAttribute = p.GetCustomAttribute <MaxLengthAttribute>();

            if (maxLengthAttribute != null)
            {
                sb.Append(string.Format(".extend({ maxLength: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", maxLengthAttribute.FormatErrorMessage(p.Name), maxLengthAttribute.Length, p.Name));
                isValidatable = true;
            }

            RegularExpressionAttribute regularExpressionAttribute = p.GetCustomAttribute <RegularExpressionAttribute>();

            if (regularExpressionAttribute != null)
            {
                sb.Append(string.Format(".extend({ pattern: { message: \"{0}\", params: /{1}/, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", regularExpressionAttribute.FormatErrorMessage(p.Name), regularExpressionAttribute.Pattern, p.Name));
                isValidatable = true;
            }

            UrlAttribute urlAttribute = p.GetCustomAttribute <UrlAttribute>();

            if (urlAttribute != null)
            {
                sb.Append(string.Format(".extend({ pattern: { message: \"{0}\", params: /{1}/, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", urlAttribute.FormatErrorMessage(p.Name), urlAttribute, p.Name));
                isValidatable = true;
            }

            DateAttribute dateAttribute = p.GetCustomAttribute <DateAttribute>();

            if (dateAttribute != null)
            {
                sb.Append(string.Format(".extend({ date: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } })", dateAttribute.FormatErrorMessage(p.Name), p.Name));
                isValidatable = true;
            }

            NumericAttribute numericAttribute = p.GetCustomAttribute <NumericAttribute>();

            if (numericAttribute != null)
            {
                sb.Append(
                    string.Format(".extend({ number: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } }).extend({ numeric: {2} })",
                                  numericAttribute.FormatErrorMessage(p.Name), p.Name, numericAttribute.Precision));
                isValidatable = true;
            }

            EmailAttribute emailAttribute = p.GetCustomAttribute <EmailAttribute>();

            if (emailAttribute != null)
            {
                sb.Append(string.Format(".extend({ email: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } })", emailAttribute.FormatErrorMessage(p.Name), p.Name));
                isValidatable = true;
            }

            DigitsAttribute digitsAttribute = p.GetCustomAttribute <DigitsAttribute>();

            if (digitsAttribute != null)
            {
                sb.Append(string.Format(".extend({ digit: { message: \"{0}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{1}\"); } } }).extend({ numeric: 0 })", digitsAttribute.FormatErrorMessage(p.Name), p.Name));
                isValidatable = true;
            }

            MinAttribute minAttribute = p.GetCustomAttribute <MinAttribute>();

            if (minAttribute != null)
            {
                sb.Append(string.Format(".extend({ min: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", minAttribute.FormatErrorMessage(p.Name), minAttribute.Min, p.Name));
                isValidatable = true;
            }

            MaxAttribute maxAttribute = p.GetCustomAttribute <MaxAttribute>();

            if (maxAttribute != null)
            {
                sb.Append(string.Format(".extend({ max: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", maxAttribute.FormatErrorMessage(p.Name), maxAttribute.Max, p.Name));
                isValidatable = true;
            }

            EqualToAttribute equalToAttribute = p.GetCustomAttribute <EqualToAttribute>();

            if (equalToAttribute != null)
            {
                sb.Append(string.Format(".extend({ equal: { message: \"{0}\", params: {1}, onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", equalToAttribute.FormatErrorMessage(p.Name), equalToAttribute.OtherProperty, p.Name));
                isValidatable = true;
            }

            CompareAttribute compareAttribute = p.GetCustomAttribute <CompareAttribute>();

            if (compareAttribute != null)
            {
                sb.Append(string.Format(".extend({ equal: { message: \"{0}\", params: \"{1}\", onlyIf: function() { return ko.utils.isPropertyValidatable(self, \"{2}\"); } } })", compareAttribute.FormatErrorMessage(p.Name), compareAttribute.OtherProperty, p.Name));
                isValidatable = true;
            }

            FormatterAttribute formatterAttribute = p.GetCustomAttribute <FormatterAttribute>();

            if (formatterAttribute != null)
            {
                sb.Append(string.Format(".formatted({0}, {1})", formatterAttribute.Formatter, JsonConvert.SerializeObject(formatterAttribute.Arguments)));
            }

            return(sb.ToString());
        }
예제 #31
0
        public static void Validate_SetOnlyProperty_ThrowsArgumentException()
        {
            CompareAttribute attribute = new CompareAttribute(nameof(CompareObject.SetOnlyProperty));

            Assert.Throws <ArgumentException>(null, () => attribute.Validate("b", s_context));
        }
예제 #32
0
        public static void Validate_Indexer_ThrowsArgumentException_Netcoreapp()
        {
            CompareAttribute attribute = new CompareAttribute("Item");

            Assert.Throws <ArgumentException>(null, () => attribute.Validate("b", s_context));
        }
        protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
        {
            List<ModelValidator> vals = base.GetValidators(metadata, context, attributes).ToList();
            DataAnnotationsModelValidationFactory factory;

            // Inject our new validator.
            if (metadata.ContainerType != null)
            {
                // Check if we have validation for this class name.
                if (ValidationManager.Validators.ContainsKey(metadata.ContainerType.Name))
                {
                    var validator = ValidationManager.Validators[metadata.ContainerType.Name];

                    // Check if we have validation for this property name.
                    if (validator.ContainsKey(metadata.PropertyName))
                    {
                        var property = validator[metadata.PropertyName];

                        // Only add validation to visible properties.
                        if (property.Visible)
                        {
                            // Required attribute.
                            if (property.Required)
                            {
                                ValidationAttribute required;

                                if (metadata.ModelType == typeof(bool))
                                {
                                    // For required booleans, enforce true.
                                    required = new EnforceTrueAttribute { ErrorMessage = property.ErrorMessage };
                                }
                                else if (metadata.ModelType == typeof(int) || metadata.ModelType == typeof(long) || metadata.ModelType == typeof(double) || metadata.ModelType == typeof(float))
                                {
                                    // For required int, long, double, float (dropdownlists), enforce > 0.
                                    required = new GreaterThanZeroAttribute() { ErrorMessage = property.ErrorMessage };
                                }
                                else
                                {
                                    required = new RequiredAttribute { ErrorMessage = property.ErrorMessage };
                                }

                                if (!AttributeFactories.TryGetValue(required.GetType(), out factory))
                                {
                                    factory = DefaultAttributeFactory;
                                }

                                yield return factory(metadata, context, required);
                            }

                            // Regular expression attribute.
                            if (!string.IsNullOrEmpty(property.RegularExpression))
                            {
                                RegularExpressionAttribute regEx = new RegularExpressionAttribute(property.RegularExpression) { ErrorMessage = property.ErrorMessage };

                                if (!AttributeFactories.TryGetValue(regEx.GetType(), out factory))
                                {
                                    factory = DefaultAttributeFactory;
                                }

                                yield return factory(metadata, context, regEx);
                            }

                            // Compare attribute.
                            if (!string.IsNullOrEmpty(property.Compare))
                            {
                                CompareAttribute compare = new CompareAttribute(property.Compare) { ErrorMessage = property.ErrorMessage };

                                if (!AttributeFactories.TryGetValue(compare.GetType(), out factory))
                                {
                                    factory = DefaultAttributeFactory;
                                }

                                yield return factory(metadata, context, compare);
                            }
                        }
                    }
                }
            }
        }
예제 #34
0
        private ValidationAttribute CopyAttribute(ValidationAttribute attribute)
        {
            ValidationAttribute result = null;

            if (attribute is RangeAttribute)
            {
                var attr = (RangeAttribute)attribute;
                result = new RangeAttribute((double)attr.Minimum, (double)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 CompareAttribute)
            {
                var attr = (CompareAttribute)attribute;
                result = new 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;
        }
예제 #35
0
 public static void Validate_SetOnlyProperty_ThrowsArgumentException()
 {
     CompareAttribute attribute = new CompareAttribute(nameof(CompareObject.SetOnlyProperty));
     Assert.Throws<ArgumentException>(null, () => attribute.Validate("b", s_context));
 }
예제 #36
0
 public static void Validate_Indexer_ThrowsTargetParameterCountException()
 {
     CompareAttribute attribute = new CompareAttribute("Item");
     Assert.Throws<TargetParameterCountException>(() => attribute.Validate("b", s_context));
 }