Как установить несколько сообщений об ошибках для разных сценариев в атрибуте Пользовательская проверка? - PullRequest
4 голосов
/ 19 октября 2010

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

Я могуполучить доступ ко всем свойствам моей модели, и я хочу иметь возможность проверять наличие нескольких условий в моей перегрузке IsValid и сообщать о них, получая различные сообщения об ошибках следующим образом (упрощенный пример).

public override bool IsValid(object value)
    {
        var model = (MyObject) value;

        //if this value is set, I don't want to do anything other checks
        if (model.Prop3)
        {
            return true;
        }

        if (model.Prop1 == "blah" && model.Prop2 == 1)
        {
            ErrorMessage = "you can't enter blah if prop 2 equals 1";
            return false;
        }

        if(model.Prop1 == "blah blah" && model.Prop2 == 2)
        {
            ErrorMessage = "you can't enter blah blah if prop 2 equals 2";
            return false;
        }


        return true;
    }

Но когдаПри этом я получаю исключение при первом обращении к ErrorMessage: «Невозможно установить свойство более одного раза.

Теперь я могу разделить свой пользовательский атрибут на несколько пользовательских атрибутов, но надеялся, что найдется способ сделать это».в одном, в противном случае, я буду повторять свое «поймать все» в каждом

//if this value is set, I don't want to do anything other checks
        if (model.Prop3)
        {
            return true;
        }

У меня уже был поиск, но я ничего не мог найти, поэтому извиняюсь, если я упускаю что-то очевидное.

заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 30 августа 2013

В MVC4 вы можете переопределить IsValid, чтобы возвращать различные сообщения как ValidationResult

public class StrongPasswordAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        if (value == null)
            return new ValidationResult("Password is required");

        var val = value.ToString();

        if (!Regex.Match(val, @"^(?=.*[a-z]).{0,}$").Success)
        {
            return new ValidationResult("Password must contain at least one lower case letter");
        }
        if (!Regex.Match(val, @"^(?=.*[A-Z]).{0,}$").Success)
        {
            return new ValidationResult("Password must contain at least one UPPER case letter");
        }
        if (!Regex.Match(val, @"^(?=.*\d).{0,}$").Success)
        {
            return new ValidationResult("Password must contain at least one number");
        }

        return ValidationResult.Success;
    }
}
1 голос
/ 09 февраля 2012

Интересный вопрос! Я могу придумать два обходных пути к этому. Так что не правильные решения, основанные на том, что вы хотите, но они могут помочь повторно использовать ваш код. Не могу создать абстрактный класс CustomAttribute с именем MyCustomAttribute (или чем-то еще), который переопределяет IsValid следующим образом:

public override bool IsValid(object value)
{
    var model = (MyObject) value;

    //if this value is set, I don't want to do anything other checks
    if (model.Prop3)
    {
        return true;
    }

    CustomValidate(model);
}

CustomValidate(MyObject model) - это ваш абстрактный метод, поэтому вы можете написать несколько пользовательских классов атрибутов, которые расширяют MyCustomAttribute и просто нуждаются в реализации логики проверки для конкретного сценария.

Таким образом, вы можете иметь два класса:

public class BlahCustomAttribute : MyCustomAttribute
{
    public override Boolean CustomValidate(MyObject obj)
    {
        if (model.Prop1 == "blah" && model.Prop2 == 1)
        {
            ErrorMessage = "you can't enter blah if prop 2 equals 1";
            return false;
        }
    }
}

public class BlahBlahCustomAttribute : MyCustomAttribute
{
    public override Boolean CustomValidate(MyObject obj)
    {
        if (model.Prop1 == "blah" && model.Prop2 == 1)
        {
            ErrorMessage = "you can't enter blah blah if prop 2 equals 1";
            return false;
        }
    }
}

Надеюсь, это поможет - не совсем то, что вы хотели, но сделают работу и ее чистоту тоже.

Другое решение - разделить запятые сообщения об ошибках в свойстве ErrorMessage и обработать их во внешнем интерфейсе (но я бы пошел с первым подходом).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...