powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / DataAnnotations, связанные объекты и ModelState.
24 сообщений из 24, страница 1 из 1
DataAnnotations, связанные объекты и ModelState.
    #36843342
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, коллеги!
Применил DataAnnotations, вместо "ручной проверки корректности полей". Получил полный п... крах надежд и предвкушений. :)
Под "ручной" я имел в виду проверку корректности ввода клиентом на стороне сервера и установку валидности ModelState в соответствии с этой проверкой.
Альтернативный вариант - указание правил для соответствующих полей в их аннотации, типа [Required(ErrorMessage = "Не заполнено имя")]. Но он приводит к неожиданным (на первый взгляд) последствиям.
Дело в том, что если объект имеет связанные объекты, то "тянутся" проверки и полей связанных с ним объектов, чего совсем бы не хотелось.
Это можно как-то предотвратить?
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843442
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Курдль,

а не пробывали вместо DataAnnotations NHibernate Validator?
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843542
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barserКурдль,

а не пробывали вместо DataAnnotations NHibernate Validator?

Не-а. А что, он будет автоматом переводить "ModelState.isValid" в "false" при обнаружении ошибки?
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843564
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barser,

К тому же нет причин предполагать, что он будет вести себя иначе, чем описанный мной механизм.
Т.е. наверняка он будет тащить по ссылке связанный объект и пытаться правила проверки применить и к нему.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843572
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
КурдльbarserКурдль,

а не пробывали вместо DataAnnotations NHibernate Validator?

Не-а. А что, он будет автоматом переводить "ModelState.isValid" в "false" при обнаружении ошибки?

Именно так.
Довольно удобно использовать...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        [Digits(6, Message="Неверно указан индекс")]
        public virtual  String PostIndex { get; set; }

        [NotEmpty(Message="Необходимо указать страну"), Pattern(@"^(\w{0}|[А-ЯЁ][А-яЁё\-\s]*[А-яЁё\.])$", Message = "Неверно указана страна")]
        public virtual  String Strana { get; set; }

        [Pattern(@"^(\w{0}|[А-ЯЁ][А-яЁё\-\s]*[А-яЁё\.])$", Message = "Неверно указан регион")]
        public virtual  String Region { get; set; }

        [NotEmpty(Message = "Необходимо указать город"), Pattern(@"^(\w{0}|[А-ЯЁ][А-яЁё\-\s]*[А-яЁё\.])$", Message = "Неверно указан город")]
        public virtual  String Gorod { get; set; }

        [NotEmpty(Message = "Необходимо указать улицу"), Pattern(@"^(\w{0}|[А-ЯЁ][А-яЁё\-\s]*[А-яЁё\.])$", Message = "Неверно указана улица")]
        public virtual  String Ulitsa { get; set; }

        [NotEmpty(Message = "Необходимо указать квартиру"), Within(0, 1000, Message = "Неверно указана квартира")]
        public virtual  String Kv { get; set; }

        [Email(Message="Неверно указана электронная почта")]
        public virtual String EmailAddress { get; set; }

ну и так далее :)
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843590
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Курдльbarser,
Т.е. наверняка он будет тащить по ссылке связанный объект и пытаться правила проверки применить и к нему.
Так ссылку на связанный объект можно просто атрибутом валидации не помечать, он ее проверять и не будет, не?
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843635
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barser
1. Довольно удобно использовать...

2. Так ссылку на связанный объект можно просто атрибутом валидации не помечать, он ее проверять и не будет, не?


1. А чем это отличается от
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
        [DisplayName("Наименование:")]
        [Required(ErrorMessage = "Не заполнено наименование")]
        public virtual string DocName{ get; set; }

        [DisplayName("Дата создания:")]
        [Required(ErrorMessage = "Не заполнена дата создания")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
        public virtual DateTime DocDateCreat{ get; set; }

        [DisplayName("Дата изменения:")]
        [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
        public virtual DateTime? DocDateModif{ get; set; }

        [DisplayName("Статус:")]
        [Range(0, 1, ErrorMessage = "Не выбран статус")]
        public virtual int DocStatus{ get; set; }

2. А я и не помечаю связанный объект никаким атрибутом. Достаточно того, что этот объект тоже имеет свои обязательные атрибуты, которые в некоторых случаях добыть неоткуда. А механизм проверки полей видит, что у "рассматриваемого" объекта есть связанные, выискивает в них обязательные поля и валит проверку.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843733
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Курдль,

механизмом проверки полей? :)
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843739
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ну то есть как бы другая либа, знающая про hibernate и про то, что есть такие proxy-объекты... и соответственно учитывающая особенности работы с ними...
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843742
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
barser,

сейчас проверю... а то может я и нагнал тут)
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843796
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
barserbarser,

сейчас проверю... а то может я и нагнал тут)

Ну да, всё так, как я и говорил.
В NHibernate Validator есть специальный атрибут:
ValidAttribute - Enables recursive validation of an associated object.
Соответственно, можно сделать вывод, что без этого атрибута проверки такой не происходит...
Есть одно НО:
сейчас закоментил [Valid] в коде, на котором проверяю, сообщения о некорректности в модели пропали, но modelState.IsValid почему-то false... Не знаю, на что ругается... Сейчас не буду разбираться, сорри.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843834
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barser,

Спасибо и на том! Я уж сам поковыряюсь, мож где-то найду решение.
Жаль смешивать в кучу валидотор от хибера со стандартным атрибутивным механизмом.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843895
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Курдльbarser,
Жаль смешивать в кучу валидотор от хибера со стандартным атрибутивным механизмом.
Если речь о смешивании в кучу атрибутов для валидации данных - то да, может быть стоит ограничиться одним хибер-валидатором (там много чего есть, а чего не хватит - напишите сами)?

А если речь об атрибутивном механизме в целом - то что плохого в том, что на класс и/или какое-либо из его полей понавешано несколько атрибутов из различных библиотек (в том числе и самописных)? Это ж удобно! Если не ошибаюсь, в таком подходе как раз один из плюсов аспектно-ориентированного программирования...
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843913
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barser,

Один убивственный довод: модель может быть использована не_NHibernate проектом.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843933
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Курдльbarser,

Один убивственный довод: модель может быть использована не_NHibernate проектом.

Although the NHibernate Validator offers special integrations with NHibernate, you can use it as a simple validation framework without NHibernate.
цитата
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36843941
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barserА если речь об атрибутивном механизме в целом - то что плохого в том, что на класс и/или какое-либо из его полей понавешано несколько атрибутов из различных библиотек (в том числе и самописных)? Это ж удобно! Если не ошибаюсь, в таком подходе как раз один из плюсов аспектно-ориентированного программирования...
1. Локализация
2. Более медленная работа при массовой заливке
3. Невозможность составления более сложных валидационных формул
4. Для ASP.NET - ставим крест на клиентской js-валидации, следовательно - дополнительные нагрузки на сервер
5. Да и вообще... ребячество это.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36844073
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
МСУ
1. Локализация

Понимаю, о чем Вы. Когда-то, когда разрабатывал "другие проги", одним из последних этапов разработки был перевод всей программы с английского на русский с помощью спец.средств типа QT Linguist. Верный подход, однако ресурсов на это сейчас нет. К тому же корректный перевод терминов предметной области на английский - сама по себе непростая задача. Так что пишем мессаджи по-русски.

МСУ
3. Невозможность составления более сложных валидационных формул

Смотря что понимать под более сложными формулами... Там довольно просто свои правила писать.

МСУ
4. Для ASP.NET - ставим крест на клиентской js-валидации, следовательно - дополнительные нагрузки на сервер

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

А вообще, насколько я понял Курдля, речь шла немножко не о том. И отвечал я про то, что атрибутами легко и удобно контроллировать различные аспекты поведения, а не только валидацию. Например, у нас используются атрибуты, определяющие изменения, которые необходимо журналировать. Хотя преимущества атрибутов для различных задач должны быть понятны и без моих слов... :)
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36844137
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barserПонимаю, о чем Вы .... Так что пишем мессаджи по-русски.
То есть, Вы представляете себе какое это зло хардкодить сообщения в бизнес-классе?

P.S. Совет - ну уж хотя бы в константы выносите, ибо атрибуты прекрасно работают с константами, без всяких левых грабель типа этих .

Код: plaintext
1.
2.
3.
public class StoredMessages
{
    public const string EmailAddressEmpty = "Неверно указана электронная почта";
}

Код: plaintext
1.
2.
3.
4.
public class Entity
{
    [DisplayName(StoredMessages.EmailAddressEmpty)]
    public virtual string EmailAddress { get; set; }
}

P.S2. StoredMessages храните в отдельной сборке. Если вдруг что - можно элементарно просто и за быстрые сроки сделать новую сборку с иной интернационализацией и подпихнуть программе. Быстро и просто, причём никаких трудозатрат. Но гадить в бизнес-классах - за это и расстрелять могут :)

barserСмотря что понимать под более сложными формулами... Там довольно просто свои правила писать.
Пример:
1. Есть 3 поля: "номер документа" (int), "тип документа" (int), "дата документа" (datetime)
2. Задача: произвести валидацию по следующему правилу:
а) Если "номер документа" находится в диапазоне [1000-10000], то "тип документа" и "дата документа" являются обязательными
б) Если "номер документа" находится в диапазоне [10001-20000], то "тип документа" является обязательным, а "дата документа" являются не обязательной
в) Если "дата документа" < DateTime.Today.AddDays(-7) и "тип документа" = [1; 10], то "номер документа" должен начинаться с цифры 9
г) ...

barserНа стороне клиента простую валидацию входных данных пишем на ExtJS. Наверное, это неправильно, так как логика проверки дублируется, но ничего лучше мы не стали выдумывать.
Во-первый, не ExtJS, а - Sencha (ExtJS погиб).
Во-вторых, чем обычные одные js-валидаторы не устроили?
В-третьих, - Вы дублируете валидационную логику и при изменении этой логики нужно вносить правки в двух местах, что есть совсем не гуд.
И в-четвертых, при сложной валидации (примеры я привел), которую невозможно описать аттрибутивно, всё-равно нужно спуститься на отдельный блок кода бизнес-класса (пусть это будет метод). А теперь представьте, что у Вас этих методов может быть сотня. И прикиньте мозгами, какой срач мы устроим в бизнес-классе?

barserА вообще, насколько я понял Курдля, речь шла немножко не о том. И отвечал я про то, что атрибутами легко и удобно контроллировать различные аспекты поведения, а не только валидацию.
Да, я понял, просто вставил свои пять грабель. И самое существенное - атрибутами легко и красиво описать модель класса хеллоуворлд. На более сложных моделях данных аттрибутивно контроллировать различные аспекты поведения будет невозможно. По опыту.

barserНапример, у нас используются атрибуты, определяющие изменения, которые необходимо журналировать. Хотя преимущества атрибутов для различных задач должны быть понятны и без моих слов... :)
Не всё так просто, коллега, не всё... :)
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36844281
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кочергой мне по-лбуМСУP.S. Совет - ну уж хотя бы в константы выносите ...StoredMessages храните в отдельной сборке.


Запамятовал. Ни в коей мере не юзайте константы в отдельной сборке, если не хотите грабель.

http://msdn.microsoft.com/ru-ru/library/ms173119.aspx
При ссылке на значения констант, определенных в другом коде, например DLL, следует соблюдать осторожность. Если новое значение константы определяется в новой версии DLL, программа по-прежнему будет хранить старое литеральное значение вплоть до перекомпиляции в новую версию.

Курите обычный статик в DLL и будет счастие.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36844356
barser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
МСУ,

в принципе, согласен с тем, что пишете, коллега. Просто у меня опыта не так много, как у Вас, очевидно. Благодарю за конструктивную критику и советы.

Насчет примера: да, для такого алгоритма валидации атрибуты отдельных свойств класса не прокатывают... У нас такие "проверки" в serviceLayer встречаются... Беру в кавычки, потому что я считал, что это к бизнес-логике больше относится (хотя и более простая валидация тоже может быть отнесена к бизнес-логике; как-то размыто получается...)

А где рекомендуете хранить такого рода проверки?
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36844801
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
barserУ нас такие "проверки" в serviceLayer встречаются... Беру в кавычки, потому что я считал, что это к бизнес-логике больше относится (хотя и более простая валидация тоже может быть отнесена к бизнес-логике; как-то размыто получается...)
Вот и я о том же :)

Получается что:

1) Аттрибутивная валидация
2) Service Layer валидация (сложная)
3) Валидация js (GUI)
4) Валидация code behind (сложная, GUI)

Каша и только.

barserА где рекомендуете хранить такого рода проверки?
Фанатам MVC и прочих ребяческих шалостей не читать
Конечно же при гуе! Б о льшую часть бизнеса (простая валидация) покроют родные js-валидаторы, которые определены декларативно. Плюсы, думаю, прорисовывать не нужно (избавляемся от лишних постбеков на сервер, при изменении правил/сообщений валидации не нужно перекомпилировать аппликацию, сообщения хранятся в ресурсниках, всё как в детском саду). Более сложную валидацию, как Вы правильно заметили, выносим в Service Layer (или при гуе) и используем там же по месту - гуевский code behind.

Имеем 2 возможных варианта:

1) Service Layer валидация (сложная)
2) Валидация js (GUI)

или

1) Валидация code behind (сложная, GUI)
2) Валидация js (GUI)

И никаких нахлёстов и дублирования, как в Вашем случае. Лично я применяю оба подхода. К примеру, если я знаю, что реально замудрёная валидация больше нигде не будет использоваться - буду юзать второй вариант. Быстро и просто.

P.S. Но не подумайте, что я против аттрибутивной валидации. Это очень красивое решение, но, к сожалению, на более серьезных и сложных проектах покрыть все проблемы не получится. Да и отказываться от родной клиентской js-валидации (опять же, вопросы по разгрузке сервера приложений) - никогда в жизни. Поэтому, это не имеет правл на жизнь, как-бы красиво оно не выглядело. Как-то так.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36845431
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати, забыл отметить, что иногда полезно и дублирование валидации (js + code behind), когда возможны атаки в обход js-валидации. Тут, глядишь, в бой вступает СУБД с обязательными полями, чеками, триггерами. Но, если ни чеков, ни триггеров нет, а обязательность необязательная (сорри за тафтологию) (надеюсь, Вы поняли о чём я) - то приходится проверять и на стороне сервера приложения. Ибо безопасность.
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36846928
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги! Чего это вы примолкли? Нехорошо бросать товарища в бидэ!

Перелопатив кучку форумов типа StackOverflow, не только не нашел решения проблемы, но и не встретил никого, у кого бы она возникла. Значицца надо что-то в консерватории подправить. Т.е. я допустил концептуальную ошибку, в чем не стесняюсь признаться. Задаю самый мой любимый вопрос: "ЧТО Я ДЕЛАЮ НЕ ТАК?"
Итак, имеем задачу - создать документ. У документа есть автор - объект класса Employee (с ним-то и проблема).
Контроллер, действие:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
        [HttpGet]
        [OutputCache(Duration = 5, VaryByParam = "id")]
        public PartialViewResult AddDocument()
        {
            Employee author = _dataManager.GetCurrentUser();
            Document document = new Document
            {
                Author = author 
            };
            ViewData.Model = document;
            return PartialView();
        }

Инициализация поля Author в объекте Document нужна, чтобы на форме показать некоторые свойства автора, напр. ФИО в поле EmpName.

Представление:
Код: plaintext
1.
2.
3.
...
<%= Html.TextBoxFor(model => model.DocName, new { @style = "width: 416px;" })%>
<%= Html.TextBoxFor(model => model.Author.EmpName, new { ReadOnly = "true", @style = "width: 416px;" })%>
...

II-я часть Мерлезонского балета (т.е. "приемная" часть действия контроллера):
Код: plaintext
1.
2.
3.
4.
5.
6.
        [HttpPost]
        public ActionResult AddDocument(Document document)
        {
            if (ModelState.IsValid) //Здесь ставим точку останова
...
        }
При корректно введенных обязательных полях документа, модель все равно не валидна.
Препарируем ModelState и видим, что там Error = 1 напротив поля Author.Login.
Да, все верно, для класса Сотрудник это поле обязательно и соотв. помечено а DataAnnotations класса Employee .
Но на вход "пост-действия" данные от формы приходят лишь с тем содержимым, которое находилось в элементах ввода формы (в нашем случае - ТекстБоксах).
А текстбокса "Author.Login", естественно не было, равно как и скрытого поля и т.п.

Что порекомендуете подправить в консерватории?
...
Рейтинг: 0 / 0
DataAnnotations, связанные объекты и ModelState.
    #36850675
Курдль
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока применил костыль, если у кого есть идеи получше - премного буду благодарен за их публикацию!
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
public class ValidateOnlyIncomingValuesAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var modelState = filterContext.Controller.ViewData.ModelState;
        var valueProvider = filterContext.Controller.ValueProvider;
 
        var keysWithNoIncomingValue = modelState.Keys.Where(x => !valueProvider.ContainsPrefix(x));
        foreach (var key in keysWithNoIncomingValue)
            modelState[key].Errors.Clear();
    }
}
Код: plaintext
1.
2.
3.
4.
[ValidateOnlyIncomingValues]
public class SomeController : Controller
{
   // ...
}
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / DataAnnotations, связанные объекты и ModelState.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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