MVC2: проверка (аннотации данных) с двумя полями зависимости - PullRequest
4 голосов
/ 02 сентября 2010

Пример: у нас есть условное поле.Это условное поле является переключателем со следующими двумя значениями «да» и «нет».Допустим, название этой радиокнопки - «ААА».

Это условное поле «AAA» должно отображаться только в том случае, если для другого поля переключателя «BBB» установлено значение «yes».(Значения переключателя «BBB» также «да» и «нет»).

Но условное поле «AAA» должно отображаться с предустановленным значением NO, значит «да» или «нет» следуетбыть установленным при первом отображении поля.

Проблема возникает из-за требования, что условное поле «AAA» ТОЛЬКО требуется, когда (безусловное) поле «BBB» установлено в «yes»- и не требуется, если для поля «BBB» установлено значение «нет».

(Звучит, что я ничего не слышал об операторе if, или? Но подождите и продолжайте читать ...)

Поверьте, для меня не будет проблемой решить эту тему, когда мы будем использовать «Состояние модели» - но мы говорим здесь о проверке (аннотации данных), которая выглядит следующим образом:

public class Input1FormModel 
{
     [Required(ErrorMessageResourceName="Error_Field_AAA_Empty",
               ErrorMessageResourceType=typeof(Resources.MyDialog))]
     public int AAA { get; set; }
}

Я также полностью понимаю эти строки кода - я верю; -)

...

//property limits
public int UpperBound { get { return DateTime.Now.Year; } }
public int LowerBound { get { return 1900; } }

...

[NotNullValidator]
[PropertyComparisonValidator("LowerBound", ComparisonOperator.GreaterThan)]
[PropertyComparisonValidator("UpperBound", ComparisonOperator.LessThanEqual)]
public int? XYZ { get; set; }

Но как решить описанную выше зависимость (AAA <-> BBB)?

Изменение «return DateTime.Now.Year;» на вызов функции, который сначала проверяет другое поле и затем возвращает true или false?Но как получить там значение другого поля?

Ответы [ 2 ]

1 голос
/ 02 сентября 2010

Вам может понадобиться использовать IDataErrorInfo.

См. этот вопрос , где я ответил на это:

Проверьте IDataErrorInfo и этот вопрос я задал о IDataErrorInfo против DataAnnotations .

0 голосов
/ 19 января 2011

Вы можете сделать это, используя аннотации данных, но аннотация должна работать на уровне класса, а не на уровне свойств, так как атрибуты validation для атрибутов отдельных свойств.

Вот пример, который я создал, потому что почтовый коднеобязательно и не требуется указывать штат, если люди сказали, что они в Новой Зеландии, но в Австралии это обязательно.Эта составная проверка принимает всю модель в качестве входного значения и использует отражение для сравнения значений имен свойств, переданных из аннотации данных.

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
public class NZPostcodeAttribute : ValidationAttribute
{
    public const string _defaultErrorMessage = "Postcode and State are required for Australian residents";
    private readonly object _typeId = new object();

    public NZPostcodeAttribute(string countryProperty, string postcodeProperty, string stateProperty)
    {
        CountryProperty = countryProperty;
        PostcodeProperty = postcodeProperty;
        StateProperty = stateProperty;
    }

    public string CountryProperty { get; private set; }
    public string StateProperty { get; private set; }
    public string PostcodeProperty { get; private set; }

    public override object TypeId
    {
        get
        {
            return _typeId;
        }
    }

    public override string FormatErrorMessage(string name)
    {
        return _defaultErrorMessage;
    }

    public override bool IsValid(object value)
    {
        PropertyDescriptorCollection props = TypeDescriptor.GetProperties(value);
        object countryValue = props.Find(CountryProperty, true).GetValue(value);
        object postcodeValue = props.Find(PostcodeProperty, true).GetValue(value);
        object stateValue = props.Find(StateProperty, true).GetValue(value);

        string countryString = countryValue == null ? "" : countryValue.ToString();
        string postcodeString = postcodeValue == null ? "" : postcodeValue.ToString();
        string stateString = stateValue == null ? "" : stateValue.ToString();


        bool isValid = true;

        if (countryString.ToString().ToLower() == "australia")
        {
            if (String.IsNullOrEmpty(postcodeString) || String.IsNullOrEmpty(stateString))
            {
                isValid = false;
            }
        }
        if (!String.IsNullOrEmpty(postcodeString))
        {
            string isNumeric = "^[0-9]+";
            if (!Regex.IsMatch(postcodeString, isNumeric))
                isValid = false;
        }
        return isValid;
    }
}

Когда вы хотите применить это к вашей модели, это нужно сделать на уровне класса модели (см. Флаг AttributeTargets.Class вверху).

Делатьэто выглядит следующим образом:

[NZPostcode("Country", "Postcode", "State")]
public class UserRegistrationModel 
{....

Вам необходимо указать атрибут проверки на имена свойств.К этому также можно добавить проверку на стороне клиента, но это будет целая статья сама по себе.

Вы можете легко адаптировать вышеприведенное к своему сценарию.

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