locked
Validation Rule RRS feed

  • Question

  • Good day,

    I am pretty new to development.  I have to add a validation rule in my telephone class to ensure that at least one telephone number exists in the collection.

    Below is my code of my class

        public class Telephone : BaseObject
    
            public Telephone(Session session)
                : base(session)
            {
            }
            public override void AfterConstruction()
            {
                base.AfterConstruction();
            }
    
            private TelephoneType _TelephoneType;
            private string _TelephoneNumber1;
            private bool _Active;
            private DateTime _DateCreated;
            private Profile _Profile;
            public TelephoneType TelephoneType
            {
                get { return _TelephoneType; }
                set { SetProperty(ref _TelephoneType, value); }
            }
    
            [RuleRegularExpression("", DefaultContexts.Save, @"^\d+$")]
            public string TelephoneNumber1
            {
                get { return _TelephoneNumber1; }
                set { SetProperty(ref _TelephoneNumber1, value); }
            }
    
            public bool Active
            {
                get { return _Active; }
                set { SetProperty(ref _Active, value); }
            }
    
            public DateTime DateCreated
            {
                get { return _DateCreated; }
                set { SetProperty(ref _DateCreated, value); }
            }
    
            [Association("Profile-TelephoneNumber")]
            public Profile Profile
            {
                get { return _Profile; }
                set { SetProperty(ref _Profile, value); }
            }
    
        }
    
        public enum TelephoneType
        {
            C = 1,
            W = 2,
            H = 3,
        }
    }

    Please advise how to go about to add the validation rule.  Is it possible to add the rule with a attribute?

    Thursday, January 11, 2018 7:54 AM

Answers

  • Hello Pikkie1234,

    If you want to add validation attribute, You need to use reflect to invoke validate method. you could take reference with the MSDN documentation.

    Define a custom attribute.

    		[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
    		public class CustomAttribute : Attribute
    		{
    			private Boolean IsEmpty;
    			public int Maxlength;
    
    			public CustomAttribute(Boolean IsEmpty)
    			{
    				this.IsEmpty = IsEmpty;
    			}
    
    			public Boolean IsValidate(string value)
    			{
    				//......
    				Console.WriteLine("IsValidate");
    				return true;
    			}
    		}

    How to use

    class Model{
    	[Custom(false, Maxlength = 10)]
    	 public string Telephone;
      }
    
          static void Main(string[] args){
    	Model model = new Model() { Telephone = "1232343432" };
    	//object[] attrs = b.GetType().GetCustomAttributes(true);
    	var fields = model.GetType().GetMembers().Where(x => x.MemberType == MemberTypes.Field);
    	foreach (MemberInfo field in fields){
    		var Customattributes = field.GetCustomAttributes(false).Select(x => x as CustomAttribute).Where(y => y != null);
    		foreach (CustomAttribute attr in Customattributes)
    		{
    			string value = ((FieldInfo)field).GetValue(model).ToString();
    			if (attr.IsValidate(value))
    			{
    						Console.WriteLine("Validate pass");
    			}
    		}
    
    	}
    }

    Hope this would be helpful!

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Edited by Fei Hu Friday, January 12, 2018 7:51 AM
    • Marked as answer by Pikkie1234 Friday, March 9, 2018 9:36 AM
    Friday, January 12, 2018 7:48 AM
  • Firstly, Telephone isn't a collection of phone numbers so it doesn't make sense to talk about applying validation of 1+ on a single object. The validation would need to occur on the type that owns the collection. A single object should validate itself.

    To add validation to a type you can either use the validation attributes defined in System.ComponentModel.DataAnnotations or write your own. But note that validation attributes really only can work on the value of a single property. While you can use an attribute to validate multiple properties you run into issues about ordering because validation may or may not occur in the order you expect.

    For more complex validation rules, including cross property checks, then you should implement IValidatableObject. This provides a method that you can do any additional validation (in addition to the attributes).

    To validate an instance you can use the Validator class.

    Going back to your original question, you cannot validate there is at least 1 phone number on a single Telephone instance but you can enforce it on the type that owns the list of instances.

    public class TelephoneCollection : Collection<Telephone>, IValidatableObject
    {
       public IEnumerable<ValidationResult> Validate ( ValidationContext context )
       {
          if (Count <= 1)
             yield return new ValidationResult("Must have at least 2 phone numbers");
       }
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, January 12, 2018 2:45 PM
  • Hello Pikkie,

    Is there any update or any other assistance I could provide? You could mark the helpful reply as answer if the issue has been solved. And if you have any concerns, please do not hesitate to let us know.

    Thank you for your understanding and cooperation.

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Pikkie1234 Friday, March 9, 2018 9:36 AM
    Sunday, January 28, 2018 1:06 PM

All replies

  • Hello Pikkie1234,

    If you want to add validation attribute, You need to use reflect to invoke validate method. you could take reference with the MSDN documentation.

    Define a custom attribute.

    		[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
    		public class CustomAttribute : Attribute
    		{
    			private Boolean IsEmpty;
    			public int Maxlength;
    
    			public CustomAttribute(Boolean IsEmpty)
    			{
    				this.IsEmpty = IsEmpty;
    			}
    
    			public Boolean IsValidate(string value)
    			{
    				//......
    				Console.WriteLine("IsValidate");
    				return true;
    			}
    		}

    How to use

    class Model{
    	[Custom(false, Maxlength = 10)]
    	 public string Telephone;
      }
    
          static void Main(string[] args){
    	Model model = new Model() { Telephone = "1232343432" };
    	//object[] attrs = b.GetType().GetCustomAttributes(true);
    	var fields = model.GetType().GetMembers().Where(x => x.MemberType == MemberTypes.Field);
    	foreach (MemberInfo field in fields){
    		var Customattributes = field.GetCustomAttributes(false).Select(x => x as CustomAttribute).Where(y => y != null);
    		foreach (CustomAttribute attr in Customattributes)
    		{
    			string value = ((FieldInfo)field).GetValue(model).ToString();
    			if (attr.IsValidate(value))
    			{
    						Console.WriteLine("Validate pass");
    			}
    		}
    
    	}
    }

    Hope this would be helpful!

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Edited by Fei Hu Friday, January 12, 2018 7:51 AM
    • Marked as answer by Pikkie1234 Friday, March 9, 2018 9:36 AM
    Friday, January 12, 2018 7:48 AM
  • Firstly, Telephone isn't a collection of phone numbers so it doesn't make sense to talk about applying validation of 1+ on a single object. The validation would need to occur on the type that owns the collection. A single object should validate itself.

    To add validation to a type you can either use the validation attributes defined in System.ComponentModel.DataAnnotations or write your own. But note that validation attributes really only can work on the value of a single property. While you can use an attribute to validate multiple properties you run into issues about ordering because validation may or may not occur in the order you expect.

    For more complex validation rules, including cross property checks, then you should implement IValidatableObject. This provides a method that you can do any additional validation (in addition to the attributes).

    To validate an instance you can use the Validator class.

    Going back to your original question, you cannot validate there is at least 1 phone number on a single Telephone instance but you can enforce it on the type that owns the list of instances.

    public class TelephoneCollection : Collection<Telephone>, IValidatableObject
    {
       public IEnumerable<ValidationResult> Validate ( ValidationContext context )
       {
          if (Count <= 1)
             yield return new ValidationResult("Must have at least 2 phone numbers");
       }
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Friday, January 12, 2018 2:45 PM
  • Hello Pikkie,

    Is there any update or any other assistance I could provide? You could mark the helpful reply as answer if the issue has been solved. And if you have any concerns, please do not hesitate to let us know.

    Thank you for your understanding and cooperation.

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Pikkie1234 Friday, March 9, 2018 9:36 AM
    Sunday, January 28, 2018 1:06 PM