1

How to validate if validation of one field is depending another field?

 [Required if Type==3]
 public long RID2 { get; set; }


 public byte Type { get; set; }

I want to get Required message if Type==3.

Filburt
  • 17,626
  • 12
  • 64
  • 115
loviji
  • 12,620
  • 17
  • 63
  • 94

2 Answers2

0

Take a look at the following question:

Custom model validation of dependent properties using Data Annotations

As a Quick look:

[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public sealed class PropertiesMustMatchAttribute : ValidationAttribute
{
   public override bool IsValid(object value)
    {
        PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
        object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
        object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
        // place here your valdiation
        return Object.Equals(originalValue, confirmValue);
    }
}

Usage:

[PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public class ChangePasswordModel
{
    public string NewPassword { get; set; }
    public string ConfirmPassword { get; set; }
}
Community
  • 1
  • 1
Jupaol
  • 21,107
  • 8
  • 68
  • 100
  • I've a simple question. To get the property values can't I get directly by casting the passed object to ChangePasswordModel? – VJAI Jul 16 '12 at 10:48
  • Well yes you could, but the idea of a Validator is to make it generic – Jupaol Jul 16 '12 at 20:40
0

Have written the attribute for you. Could be refactored a bit if you wish but the idea is the following.

using:

[RequiredIfTypeIs("Type", 3)]
public long RID2 { get; set; }

public byte Type { get; set; }

the tests for the attribute:

[TestFixture]
public class RequiredIfTypeIsAttributeTests
{
    private class YourModel
    {
        [RequiredIfTypeIs("Type", 3)]
        public long RID2 { get; set; }

        public byte Type { get; set; }

    }

    private class TestRequiredIfTypeIsAttribute : RequiredIfTypeIsAttribute
    {
        public TestRequiredIfTypeIsAttribute(string typePropertyName, byte requiredTypePropertyValue)
            : base(typePropertyName, requiredTypePropertyValue)
        {
        }

        public ValidationResult TestIsValid(object value, ValidationContext validationContext)
        {
            return IsValid(value, validationContext);
        }
    }

    [Test]
    public void TypeIs3_RidIs0__Return_IsNotValid()
    {
        var yourModel = new YourModel()
        {
            RID2 = 0,
            Type = 3,
        };

        TestValidationWithModel(yourModel, false);
    }

    [Test]
    public void TypeIs2_RidIs0__Return_IsValid()
    {
        var yourModel = new YourModel()
        {
            RID2 = 0,
            Type = 2,
        };

        TestValidationWithModel(yourModel, true);
    }

    [Test]
    public void TypeIs3_RidIs1__Return_IsValid()
    {
        var yourModel = new YourModel()
        {
            RID2 = 1,
            Type = 3,
        };

        TestValidationWithModel(yourModel, true);
    } 

    private void TestValidationWithModel(YourModel yourModel, bool success)
    {
        var validationContext = new ValidationContext(yourModel, null, null);
        var attribute = new TestRequiredIfTypeIsAttribute("Type", 3);
        var result = attribute.TestIsValid(yourModel.RID2, validationContext);

        Assert.AreEqual(success, result == ValidationResult.Success);
    }
}

And the attribute class:

public class RequiredIfTypeIsAttribute : ValidationAttribute
    {
        private string _typePropertyName;
        private byte _requiredTypePropertyValue;

        public RequiredIfTypeIsAttribute(string typePropertyName, byte requiredTypePropertyValue) : base()
        {
            _typePropertyName = typePropertyName;
            _requiredTypePropertyValue = requiredTypePropertyValue;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var comparedPropertyInfo = validationContext.ObjectType.GetProperty(_typePropertyName);

            var propertyValue = (byte) comparedPropertyInfo.GetValue(validationContext.ObjectInstance, null);

            bool valid = true;

            if (propertyValue == _requiredTypePropertyValue)
            {
                valid = false;

                int checkedValue;

                if (int.TryParse(value.ToString(), out checkedValue))
                {
                    if (checkedValue > 0)
                    {
                        valid = true;
                    }
                }
            }


            if (!valid)
            {
                var message = base.ErrorMessage;
                return new ValidationResult(message);
            }
            return null;
        }
    }
Dmitry Khryukin
  • 6,408
  • 7
  • 36
  • 58