如何将对象传递给自定义数据注释验证器

时间:2011-08-26 10:36:16

标签: c# data-annotations

我想创建一个自定义数据注释验证器,以检查列表中的所有项是否唯一。例如

public class AnyClass{

  [Unique]
  public List<string> UniqueListOfStrings;
}

现在我的Unique属性看起来像这样

public sealed class UniqueAttribute : ValidationAttribute
{

    public UniqueAttribute()
        : 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;
    }
}

直到现在它还可以,但是我想让属性更通用,因为我可以传递实现IEqualityComparer<T>的任何类的对象。这样我的新IsValid方法就像

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;
}

问题是我无法发送对象。是否有任何解决方法,以便我可以使用比较器类来比较对象。

1 个答案:

答案 0 :(得分:4)

我没有找到任何将对象传递给自定义数据注释验证器的解决方案,但解决了我制作自定义数据注释验证器以检查列表中的所有项是否唯一的问题。这是代码:

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;
}

我所做的是,而不是假设比较任何实现IEqualityComparer<T>的类,我现在假设我将比较任何实现IComparable接口的类。这样我就可以实现Unique自定义属性。