There are a few cases where you want to be able to validate a property value based on the value of another property. As always there are a bunch of different solutions to this problem, but the cleanest way of doing so is to create a custom DataAnnotaion validation attribute.
It is as easy as creating a class derived from ValidationAttribute and overriding the IsValid-method, but instead of the usual IsValid(object value) we will be overriding the IsValid(object value, ValidationContext validationContext) method.
The ValidationContext contains information about the current object beeing validated and makes it possible to get the values of related properties. By including the related properties and values in our validation class constructor. All in all, it could look like this, even though the validation logic does not really make sense in a real world context it explains the idea pretty good.
When using the attribute we will simply atach it to the property with the related property name as an argument.
Using this technique it is easy to create extremely flexible and advanced validation based on several property values on any object.
It is as easy as creating a class derived from ValidationAttribute and overriding the IsValid-method, but instead of the usual IsValid(object value) we will be overriding the IsValid(object value, ValidationContext validationContext) method.
The ValidationContext contains information about the current object beeing validated and makes it possible to get the values of related properties. By including the related properties and values in our validation class constructor. All in all, it could look like this, even though the validation logic does not really make sense in a real world context it explains the idea pretty good.
[AttributeUsage(AttributeTargets.Property)] public class CustomValidationAttribute : ValidationAttribute { public string PropertyName { get; private set; } public CustomValidationAttribute(string propertyName) { PropertyName = propertyName; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if(validationContext == null) return null; var property = validationContext.ObjectType.GetProperty(PropertyName); if (property == null) return new ValidationResult(string.Format(CultureInfo.CurrentCulture, "Unknown property " + PropertyName)); var propertyValue = property.GetValue(validationContext.ObjectInstance, null); if(string.IsNullOrWhiteSpace((string)propertyValue)) return new ValidationResult(string.Format(CultureInfo.CurrentCulture, PropertyName + " value is null")); if (string.IsNullOrWhiteSpace((string)value)) return new ValidationResult(ErrorMessage); return null; } }
When using the attribute we will simply atach it to the property with the related property name as an argument.
[CustomValidation("FirstName", ErrorMessage = "FirstName must not be null or empty")] public string LastName { get; set; }
Using this technique it is easy to create extremely flexible and advanced validation based on several property values on any object.
Comments
Post a Comment