Лапшекодим валидацию, или запрещаем вводить неправильные данные?
Вот если бы это так и работало, без той лапши, на которую я ссылку дал.
А теперь скажите, зачем нужен валидатор StringLength, если я могу использовать контрол с ограничением по длине строки?
По мне, луче иметь такую модель (проперти для примера)
Name
NameMaxLength
DisplayName
Age
AgeMin
AgeMax
чем такую
[StringLength]
[Display]
Name
[Range]
Age
Первая и привязывается к чему угодно без проблем, и сериализуется тоже без проблем. И безо всякого лапшекода. Имя привязывается к контролу со встроенным ограничителем на длину строки, и к этому же ограничителю привязывается NameMaxLength. Когда вводишь больше ограничителя, то просто прекращается ввод - не надо никаких сообщений об ошибках. То же с возрастом - привязываем его не к голому текстбоксу, а к нормальному NumericUpDown, в котором есть проверка диапазона, границы которого тоже легко привязываются к свойствам модели.
Всё! Не надо лапши, рефлексии, обязательного базового класса с реализацией допотопных неудобных интерфейсов, и трахания с сериализацией. Вам только кажется, что атрибуты это красиво и удобно. Оно красиво толкьо когда их один-два и они коротко объявлены. А когда каша из атрибутов с кучей установок их свойств (типа притаранить локализованное сообщение об ошибке - укажи словарь, укажи ключ, укажи собственно свойства атрибута), то вся красота и лаконичность быстро исчезают. Вот это что, читаемо (смотри ниже)? А я тут всего два атрибута написал. Некоторые навешивают по пять-шесть. Можно и в одну строку написать - будете скроллить экран по горизонтали. Особенно если у вас ноутбук с маленьким экраном. Писал, писал я подобную фигню, вытаскивал данные из атрибутов рефлексией... а потом подумал - а нафига оно надо? И стал всё в обычных пропертях писать.
[NameDescription( resourceType: typeof(Namespace1.Namespace2.Namespace3.Namespace4.Strings), name: "AAAName", description: "AAADescription")] [Range( 1.0, 20.0, ErrorMessageResourceType: typeof(Namespace1.Namespace2.Namespace3.Namespace4.Strings), ErrorMessageResourceName : "AAAErrorMessage")] public double AAA { get; set; } = 1.6;