Я написал свою логику проверки с использованием простого c #, мой бизнес-уровень содержит эти проверки, и я использую блоки try и catch для всего бизнес-уровня. Уровень представления улавливает эти пользовательские исключения, поэтому ошибки выводятся на экран пользователю. Я сохранил только базовую проверку в аннотациях данных, например, [Требуется] в основном для вызовов ajax и для уведомления пользователей о вводе данных в необнуляемые поля, чтобы моя бизнес-логика оставалась на среднем уровне, она оставалась согласованной, она оставалась только в одном месте, к которому я могу обратиться.