Как передать объект в специальный валидатор аннотаций данных - PullRequest
1 голос
/ 26 августа 2011

Я хочу создать собственный валидатор аннотаций данных, чтобы проверить, являются ли все элементы в списке уникальными или нет. Например

public class AnyClass{

  [Unique]
  public List<string> UniqueListOfStrings;
}

Теперь мой уникальный атрибут выглядит следующим образом

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 Ответ

4 голосов
/ 08 сентября 2011

Я не нашел какого-либо решения для передачи объекта в пользовательский валидатор аннотаций данных, но решил свою проблему создания пользовательского валидатора аннотаций данных, чтобы проверить, являются ли все элементы в списке уникальными или нет. Вот код:

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.

...