powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Валидация в одном месте
25 сообщений из 52, страница 1 из 3
Валидация в одном месте
    #39053426
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут статья на Хабре вышла. Собственно, уже не раз о подобном говорили. И там с первых же комментов идёт предложение вариантов.

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

Код: c#
1.
2.
[Range (1, 10)]
int Length { get; set; }



то модель представления, например, будет

Код: c#
1.
2.
3.
int Length { get; set; }
int LengthMinimum { get; set; }
int LengthMaximum { get; set; }



Почему я заюзал отдельные свойства для каждого свойства атрибута, а не сами атрибуты вкорячил в модель представления? Потому что работа с атрибутами в C# - боль. Я, конечно, написал себе хелперы для вытаскивания атрибутов, по типу такого

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
/// <summary>
        /// Gets specified property of the specidied type. Then gets specified attribute of the previously got property.
        /// Then gets value of the specified attribute property of the previously got attribute.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="propertyName"></param>
        /// <param name="attributeType"></param>
        /// <param name="attributePropertyName"></param>
        /// <param name="ci"></param>
        /// <returns></returns>
        public static object GetAttributePropertyValue(
            Type type,
            string propertyName,
            Type attributeType,
            string attributePropertyName, 
            CultureInfo ci)
        {
            PropertyInfo propInfo = type.GetProperty(propertyName);
            var attr = propInfo.GetCustomAttribute(attributeType);
            PropertyInfo attributePropInfo = attr.GetType().GetProperty(attributePropertyName);
            var attrPropValue = attributePropInfo.GetValue(
                attr,
                System.Reflection.BindingFlags.Default,
                null,
                new object[] { },
                ci);

            return attrPropValue;
        }



но это я использую при инициализации модели представления - достаю из атрибутов модели эти данные и присваиваю свойствам модели представления. В противном случае пришлось бы копировать атрибуты модели в атрибуты модели представления (та ещё морока), а затем в представлении вытаскивать атрибуты модели представления через конвертеры. Только конвертеры будут отрабатывать всякий раз при изменении занчения в контроле, а мой способ - только один раз при инициализации модели представления.

Ну а и далее валидация в модели представления. В WPF всё просто - юзаем контролы, в которых уже валидация встроена - всякие

Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
<fluent:Spinner
      Value="{Binding Path=...}"
      Minimum="{Binding Path=LengthMinimum}" 
      Maximum="10" <!-- неправильно - надо через байндинги - также и внизу... но если очень хочется, можно и руками написать, конечно -->
      Increment="1"
      Format="0"
      IsEnabled="{Binding ElementName=..., Path=..., Converter={StaticResource ...}}" 
/>



Т. е. логику валидации на клиенте дублировать не надо - всё уже встроено в контрол, которому надо просто привязать соответствующие поля в соответствующие свойства.

С вебом также - не надо юзать голый HTML. Надо юзать продвинутые контролы. Тогда не будет надобности дублировать логику валидации в виде простыни кода, который копипастят по всем слоям, а потом забывают обновлять, если где-то в одном месте изменили. Если нет продвинутых HTML-javascript-контролов, то да - придётся писать самому эту кучку джаваскрипта для валидации.

Т. е., ещё раз - правильно валидировать на слоях:

1) юзать валидацию, разбитую на атомарные операции (типа валидация минимума, валидация максимума, валидация формата и пр.), и при этом каждая такая операция - в собственном классе, как приведённые атрибуты. Ну а то, что эти классы - атрибуты - просто такой удобный вариант исполнения. Удобно на модели атрибуты расставлять, а не заполнять методы типа Validate простынями кода, как в статье в примере;

2) юзать продвинутые контролы, в которые такая атомарная валидация (т. е. валидация по каждому аспекту, вынесенная в отдельный блок кода - класс) встроена и работает на их свойствах. Тогда остаётся только просто достать свойства из модели и присвоить их нужным свойствам контрола;

3) юзать модели для каждого слоя, в которых валидируемые параметры представлены в виде свойств (как у меня выше в примере LengthMinimum и т. п.) или тоже атрибутов (этого я в примере с Length не показал). При этом эти свойства заполняются из первоначальной доменной модели - т. е. вытаскиваем из неё максимумы, минимумы, шаблоны форматов в виде регулярок или там текстовых масок и прочее.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053427
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что скажете и как делаете вы?
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053429
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЕсли нет продвинутых HTML-javascript-контролов, то да - придётся писать самому эту кучку джаваскрипта для валидации.
Но, опять же, вытаскивать параметры валидации (максимум, минимум и т. п.) из доменной модели. А для этого сначала перенести эти параметры из доменной модели в модель представления. Вот что я имел ввиду.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053430
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор1) юзать валидацию, разбитую на атомарные операции (типа валидация минимума, валидация максимума, валидация формата и пр.), и при этом каждая такая операция - в собственном классе, как приведённые атрибуты. Ну а то, что эти классы - атрибуты - просто такой удобный вариант исполнения. Удобно на модели атрибуты расставлять, а не заполнять методы типа Validate простынями кода, как в статье в примере;
Тут вот в чём штука. Автор в статье гонял код валидации по всем слоям копипастой. Но дело в том, что валидация, разбитая на атомарные операции представляет из себя скорее значения параметров валидации, а не сами действия и код проверки. Например, LengthMinimum всегда будет проверяться кодом типа

if (Length < LengthMinimum)

Т. е. именно на меньше, а не на больше или равно (для включающего интервала - т. е. для меньше или равно - надо заводить атрибут LengthMinimumOrEqual - т. е. собладать принцип атомарности). Поэтому нет смысла инкапсулировать сам код проверки в методах типа Validate, как у автора статьи. Достаточно инкапсулировать только параметры атомизированной валидации. Поэтому атрибуты, в которых в свойствах хранятся такие параметры, а сама логика - инкапсулирована в их коде как в отдельном классе, подходят для этого лучше всего.

Т. е. выносить валидацию в отдельный метод Validate, где писать простыню кода валидации (т. е. мешать всё в кучу, без атомарности - без разделения каждого аспекта валидации) - это устаревший подход и годится только в специфических случаях, когда валидация на атрибутах невозможно или слишком затруднена. Ну или когда не охота заморачиваться написанием полноценных моделей для слоёв и надо всё по-быстрому на коленке запиндюрить.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053434
Фотография Где-то в степи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88,
все зависит от мечпохи работы с объектами, посмотрите как сделан IValidatable в хибернате, был там интерфейс и
реализующий beforeInsert() afterInsert() ( рыться не охота)
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053437
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Подход автора статьи - вынесение валидации в некий атомарный объект Email. Плохо то, что если потребуются разные логики валидации, придётся либо городить два разных типа (Email и EmailWithSpecificValidation), либо расширять Email всякими параметрами. Кроме того, придётся расшарить тип Email между всеми слоями - даже между теми, где валидация не требуется. Ну и сам объект со свойством Email тоже надо будет расшарить на все слои с валидацией.

С атрибутами же подход вернее - выделяются на валидируемые объекты, а сама валидация.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053439
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степиWebtester88,
все зависит от мечпохи работы с объектами, посмотрите как сделан IValidatable в хибернате, был там интерфейс и
реализующий beforeInsert() afterInsert() ( рыться не охота)
Что за выделенное слово?

Т. е. Хайбернейт вводит свой интерфейс, вместо того, чтобы использовать уже готовый в общеупотребительном фреймворке? Или как?

Я либо должен этот IValidatable на все модели с валидацией распространить, либо таки в методах beforeInsert и т. п. использовать таки свою доменную долику валидации. Я предпочитаю последний подход.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053443
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WPF: ValidationRule

HTML: Knockout-Validation

Главное, не надо ничего усложнять.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053444
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Где-то в степиWebtester88,
все зависит от мечпохи работы с объектами, посмотрите как сделан IValidatable в хибернате, был там интерфейс и
реализующий beforeInsert() afterInsert() ( рыться не охота)
Я не знаком с Хайбернейтом - юзаю EF. Там в code first фактически создаётся модель слоя данных. - Можно в этой модели создать те же свойства LengthMinimum и т. п. (только задать, чтобы они в БД не сохранялись - т. е. свойства только для валидации). Ну и при сохранении модели данных в БД валидировать её через эти свойства. Валидировать, например, в репозитории или затолкать код в подобия ваших beforeInsert().
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053450
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КWPF: ValidationRule

HTML: Knockout-Validation

Главное, не надо ничего усложнять.
ValidationRule кажется какой-то устаревшей вещью. Т. е. она, конечно, работает, но не так удобно, как в контролах, в которых валидация уже встроена в свойства.

С этим ValidationRule ты должен заводить специальные поля напротив полей ввода, которые бы подсказывали, в чём ошибка и т. п. Контролы просто не дадут тебе сделать эту ошибку. Т. е. вот это или вот это - это какие-то лютые простыни кода.

Возьмём первый пример Джоша Смита. Там юзается банальный текстбокс для ввода числа и текстблок для вывода сообщения об ошибке. Плохое - в выделенном мной куске текста. Надо юзать готовый контрол для ввода именно чисел , в котором уже будет встроено:

- само значение
- нижняя граница
- верхняя граница
- формат числа
- (опционально) инкремент-декремент, если это контрол с кнопками увеличения-уменьшения значения
- ну и т. д.

Городьба простынь как у Джоша - из-за неразвитости контролов в WPF в то время, когда он писал свою букварь. Я тоже так раньше писал - и я, честно говоря, заманался в каждом проекте дублировать эти простыни однотипного кода. А вот подход с нормальными контролами упростил дело - завёл нужную модель представления с нужными свойствами и разметка чиста - одни контролы с привязками без всяких errorMessageTextBlock на каждый чих, которые ещё и место в UI кушают.

Согласен?
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053454
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ещё раз - Джош сам создал проблему (использовал голый текстбокс для ввода чисел - естественно, в этом текстбоксе нет никаких удобств для ввода именно чисел ) и сам с честью её преодолел.

Я не знаю, почему он так сделал. Возможно, просто для иллюстрации своего подхода. Т. е. вот так можно валидировать, но ИМЕННО ВОТ ТАК в реальных проектах валидировать не надо. Т. е. подход с числами для текстбокса был выбран только в качестве удобной и простой иллюстрации подхода, а не реально употрибемого кода. А может, просто не было в его время таких удобных контролов (в 2008 всё же мало ещё для WPF понаписали). Не знаю. Но сейчас мне его подход однозначно кажется архаичным и требующим кучи лишних телодвижений.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053456
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот когда у меня флюэнтовский спиннер отберут, а заодно и другие реализации спиннера и прочих контролов для ввода чисел, вот тогда "и снова здравствуй, Джош!".

С тревогой думаю, как переходить на store applications и всякие continuity с автртрансформацией интерфейса для различных режимов работы. Есть ли там из коробки готовые удобные контролы, или опять один тексбокс на все случаи жизни? В WPF уже столько сметаны с маслом и сосисками поналожили, что моему внутреннему коту уходить из этого рая очень не хочется.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053459
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обрати внимание, Алексей

авторКонтролы просто не дадут тебе сделать эту ошибку.

Меня от этого пропёрло. Вместо того, чтобы валидировать каждый пользовательский чих - а пользователь обязательно придумает ситуацию, как сломать твою программу - лучше забрать у него возможность совершать сами ошибки. KISS , внатуре. Эппл-стайл с одной кнопкой на экран, если хотите утрированно. )))
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053463
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88Алексей КWPF: ValidationRule

HTML: Knockout-Validation

Главное, не надо ничего усложнять.
ValidationRule кажется какой-то устаревшей вещью. Т. е. она, конечно, работает, но не так удобно, как в контролах, в которых валидация уже встроена в свойства."Всё новое - это хорошо забытое старое" (ц)
Webtester88С этим ValidationRule ты должен заводить специальные поля напротив полей ввода, которые бы подсказывали, в чём ошибка и т. п. Контролы просто не дадут тебе сделать эту ошибку. Т. е. вот это или вот это - это какие-то лютые простыни кода.Там ничего особенного не надо. Назначаешь стилем универсальный Validation.ErrorTemplate, визуализирующий ошибку, и всё.
Webtester88Возьмём первый пример Джоша Смита. Там юзается банальный текстбокс для ввода числа и текстблок для вывода сообщения об ошибке. Плохое - в выделенном мной куске текста. Надо юзать готовый контрол для ввода именно чисел , в котором уже будет встроено:

- само значение
- нижняя граница
- верхняя граница
- формат числа
- (опционально) инкремент-декремент, если это контрол с кнопками увеличения-уменьшения значения
- ну и т. д.

Городьба простынь как у Джоша - из-за неразвитости контролов в WPF в то время, когда он писал свою букварь. Я тоже так раньше писал - и я, честно говоря, заманался в каждом проекте дублировать эти простыни однотипного кода. А вот подход с нормальными контролами упростил дело - завёл нужную модель представления с нужными свойствами и разметка чиста - одни контролы с привязками без всяких errorMessageTextBlock на каждый чих, которые ещё и место в UI кушают.

Согласен?Особых неудобств в прикладном коде я не заметил:
Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
        <TextBox>
            <TextBox.Text>
                <Binding Path="PropertyName">
                    <Binding.ValidationRules>
                        <s:NotNullRule/>
                        <my:SomeCustomRule/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053465
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88Обрати внимание, Алексей

авторКонтролы просто не дадут тебе сделать эту ошибку.

Меня от этого пропёрло. Вместо того, чтобы валидировать каждый пользовательский чих - а пользователь обязательно придумает ситуацию, как сломать твою программу - лучше забрать у него возможность совершать сами ошибки. KISS , внатуре. Эппл-стайл с одной кнопкой на экран, если хотите утрированно. )))"Попытаться не дать пользователю ошибиться" - это альтернативный подход, который в общем случае менее гибок. Не вижу смысла "ломать WPF-традиции" ради каких-то там предрассудков. :-)
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053471
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей К,

ладно, я согласен с тем, что кто как привык, тому так и удобно. Я ValidationRule не особо изучал и забил на это дело. Нашёл продвинутые контролы и они мне показались удобнее. Кстати, ValidationRule работает не только в контексте WPF? Или только? Оно работает в ASP.NET MVC, Store Apps из коробки? Т. е. есть смысл его изучать как универсальное средство?

А что насчёт общего подхода к валидации - атрибуты там и передача их в разные слои в виде дополнительных свойств на этих слоях (типа LengthMinimum и т. п.)?
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053482
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88Алексей К,

ладно, я согласен с тем, что кто как привык, тому так и удобно. Я ValidationRule не особо изучал и забил на это дело. Нашёл продвинутые контролы и они мне показались удобнее. Кстати, ValidationRule работает не только в контексте WPF? Или только? Оно работает в ASP.NET MVC, Store Apps из коробки? Т. е. есть смысл его изучать как универсальное средство?Только в WPF. В других UI библиотеках обычно есть аналоги. Один их них я привёл выше.

Webtester88А что насчёт общего подхода к валидации - атрибуты там и передача их в разные слои в виде дополнительных свойств на этих слоях (типа LengthMinimum и т. п.)?Я не вижу в этом смысла, но это моё субъективное мнение, я не настаиваю. :-)
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053493
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КWebtester88А что насчёт общего подхода к валидации - атрибуты там и передача их в разные слои в виде дополнительных свойств на этих слоях (типа LengthMinimum и т. п.)?Я не вижу в этом смысла, но это моё субъективное мнение, я не настаиваю. :-)
А как ты делаешь валидацию? У тебя правила валидации хранятся в одном месте?

Я предложил подход, когда правила хранятся в одном месте, но их можно применять в разных местах, не выделяя для этого какой-то отдельный объект валидации (как класс Email, содержащий логику валидации, в статье автора по ссылке в первом посте). Этот подход можно применяь по всему стеку .NET, а не только в WPF или там в ASP.NET.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053515
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88Алексей Кпропущено...
Я не вижу в этом смысла, но это моё субъективное мнение, я не настаиваю. :-)
А как ты делаешь валидацию? У тебя правила валидации хранятся в одном месте?У меня обычно есть две валидации:

1. Основная, серверная: при вызове метода веб-сервиса вроде SaveSomeEntity возвращается ошибка, которая обычно показывется в MessageBox-диалоге или как-то иначе. Некрасиво, зато сердито и надёжно.

2. Дополнительная клиентская валидация: делается на клиенте средствами UI-библиотеки вроде ValidationRule в WPF и т. п. Здесь дублируется часть простой серверной логики вроде обязательности полей, их форматов, диапазонов и т. п. Красиво, но не покрывает все возможные проверки, используется в качестве бантика "для красоты".
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053528
kmaw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"валидация" - не хорошее слово. по сути - это (основная часть бизнес-логики) проверка состояния объекта на допустимость. место этой логике в слое сервисов. как эти ошибки показать в UI - это варианты реализации UI, не более
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053539
kmaw
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88Можно в этой модели создать те же свойства LengthMinimum и т. п. (только задать, чтобы они в БД не сохранялись - т. е. свойства только для валидации)

Webtester88 Валидировать, например, в репозитории

адский ад.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053558
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88Что скажете и как делаете вы?доменная модель отдельно, валидация отдельно
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053568
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
skyANAWebtester88Что скажете и как делаете вы?доменная модель отдельно, валидация отдельно
У меня тоже так. Только атрибуты валидации на доменной модели никому не мешают (они же не тормозят вычисления?).
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053569
Webtester88
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88skyANAпропущено...
доменная модель отдельно, валидация отдельно
У меня тоже так. Только атрибуты валидации на доменной модели никому не мешают (они же не тормозят вычисления?).
В смысле, что я валидацию не в доменном слое провожу. Но храню граничные значения для валидации - в доменном слое.
...
Рейтинг: 0 / 0
Валидация в одном месте
    #39053754
Фотография skyANA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Webtester88skyANAпропущено...
доменная модель отдельно, валидация отдельно
У меня тоже так. Только атрибуты валидации на доменной модели никому не мешают (они же не тормозят вычисления?).Как реализуете разные проверки в разных компонентах системы?
...
Рейтинг: 0 / 0
25 сообщений из 52, страница 1 из 3
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Валидация в одном месте
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]