Re[3]: Опять валидация данных
От: IT Россия linq2db.com
Дата: 15.03.05 15:08
Оценка: 22 (5) +1
Здравствуйте, Козьма Прутков, Вы писали:

КП>Рассмотрим веб-приложение (ибо сложнее), но аналогично и винформовое. Пусть по первоначальным требованиям поле Заказчик обязательное. Ок, сделали. Через 3 месяца оказывается, что оно не является обязательным. И мы шагом марш по всем уровням валидации это дело править. Или я чего-то не понял?

КП>Таперь рассмотрим винформс-приложение (в веб-приложении решается написанием метода установки пары значений). Вот подвязана у нас к свойствам Country и ZipCode (он же индекс для примера) пара контролов. По идее, если пользователь меняет один из них, то нужно проверить их пару. Так что пользователь, однажды введя US/12345 уже никогда не введет RU/131000, ибо перекрестные комбинации невалидны. Ну, либо позволить перевести БО в неконсистентное состояние, что вряд ли очень хорошо.

Ты говоришь о валидации непосредственно во время ввода, о валидации каждого введённого символа. Мне эта практика кажется крайне порочной как раз по причинам, которые ты описываешь. Формы, которые думают что они умней меня всегда раздражают. Валидация значений и их комбинаций должна делаться при сабмите формы. Во время ввода можно проверять только формат, типа ничего не давать пользователю вводить кроме цифр и т.п.

Что же касается первого вопроса об изменениях по всем уровням валидации, то здесь я видимо не совсем ясно выразился. Говоря "этот уровень повторяет все проверки предыдущего" я не имел ввиду дублирование кода, я имел ввиду его повторное использование. Например, имеем вот такой класс Address:

public class Address : BizEntityBase
{
    [MaxLength(35), Required] public string      Address1;
    [MaxLength(35)          ] public string      Address2;
    [MaxLength(35), Required] public string      City;
    [MaxLength(35), Required] public string      Region;
    [               Required] public string      PostalCode;
    [               Required] public CountryCode CountryCode;

    public override void Validate()
    {
        // 1-й уроовень.
        //
        base.Validate();

        // 2-й.
        //
        switch (CountryCode)
        {
            case CountryCode.US:
                if (PostalCode.Length != 5 || PostalCode.Length != 9)
                    throw new Exception("Zip must be 5 or 9 digits.");
                break;

            case CountryCode.RU:
                if (PostalCode.Length != 6)
                    throw new Exception("Почтовый индекс должен содержать 6 цифр.");
                break;
        }
    }
}

Здесь в одном месте реализованы 1-й и 2-й уровни валидации. Третий в бизнес объекте:

public class AddressService : ServiceBase
{
    public void AddAddress(Address address)
    {
        // 1-й, 2-й.
        //
        address.Validate();

        // 3-й. Вызываем код проверки адреса на существование.
        // Используем софт компании Address Validation, Inc.
        //
        new Agents.AddressValidator().Validate(address);

        // Сохраняем обхект в БД.
        //
        new AddressDataAccessor().AddAddress(address);
    }
}

4-й в БД.

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'U' AND name = 'Address')
BEGIN
    PRINT 'Dropping Table Address'
    DROP   Table    Address
END
GO

PRINT 'Creating Table Address'
GO

CREATE TABLE dbo.Address
(
    AddressID  int IDENTITY (1,1) NOT NULL CONSTRAINT PK_Address PRIMARY KEY CLUSTERED,
    Address1       nvarchar(35)   NOT NULL,
    Address2       nvarchar(35),
    City           nvarchar(35)   NOT NULL,
    Region         nvarchar(35)   NOT NULL,
    PostalCode     nvarchar(11)   NOT NULL,
    CountryCode    udt_CountryCode
) ON [PRIMARY]

GRANT SELECT ON Customer TO PUBLIC
GO

Теперь, допустим, нам нужно одно из полей сделать необязательным. Сколько нужно сделать изменений? Правильно, две. Первое — убрать Required атрибут в классе, второе — NOT NULL в SQL скрипте. Готовоо.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.