How to pass a object to a custom Data annotation Validator
I want to create a custom Data annotation Validator to check whether all the items in the list is unique or not. For example
public class AnyClass{
[Unique]
public List<string> UniqueListOfStrings;
}
Now my Unique attribute look like this
public sealed class UniqueAttribute : ValidationAttribute
{
public UniqueAttr开发者_JAVA百科ibute()
: base("The items are not unique")
{
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var listOfValues = (IList<object>)value;
return listOfValues.Count != listOfValues.Distinct().Count()
? new ValidationResult(ErrorMessageString)
: ValidationResult.Success;
}
}
Till now it is fine, but I want to make the attribute more generic in a sense that I can pass object of any class implementing IEqualityComparer<T>
. In that way my new IsValid
method will look like
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var listOfValues = (IList<object>)value;
return listOfValues.Count !=
(_comparerClass != null
? listOfValues.Distinct(_comparerClass).Count()
: listOfValues.Distinct().Count())
? new ValidationResult(ErrorMessageString)
: ValidationResult.Success;
}
The problem is I am no way able to send the object. Is there any workaround so that I can use comparer class intended to compare the objects.
I didn't find any solution to pass object to a custom Data annotation validator, but solved my problem of making a custom Data annotation Validator to check whether all the items in the list is unique or not. Here is the code:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if(value == null)
return ValidationResult.Success;
var iComparableValues = ((IList)value).Cast<IComparable>().ToList();
return AreElementsUnique(iComparableValues)
? ValidationResult.Success
: new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
private static bool AreElementsUnique(IList<IComparable> listOfValues)
{
var length = listOfValues.Count;
for(var i = 0;i< length;i++ )
{
for(var j =i+1; j< length;j++)
{
if(listOfValues[i].CompareTo(listOfValues[j]) ==0)
return false;
}
}
return true;
}
What I did is, instead of assuming that comparing any class implementing IEqualityComparer<T>
, I am now assuming I will compare any class implementing IComparable interface. This way I was able to implement the Unique custom attribute.
精彩评论