Как сделать поле обязательным, исходя из значения другого поля

У меня есть ViewModel с некоторыми общедоступными свойствами, которые имеют аннотации данных, например:

[Required]
public string PointOfContact { get; set; }

Что отлично работает. У меня есть вся необходимая сантехника для отображения правильного форматирования элементов управления и сообщений об ошибках в случае сбоя проверки.

Однако у меня есть некоторые поля, требующие условно в зависимости от значения флажка. Например:

public bool Briefing { get; set; }
public DateTime BriefingTime { get; set; }

В этом случае я хочу, чтобы BriefingTime требовался только в том случае, если установлен флажок, привязанный к свойству Briefing. Видимость BriefingTime уже привязана к Briefing, поэтому все, что мне нужно, - это иметь обычное поведение Required при установленном флажке.

Есть ли способ сделать это из коробки или мне нужно написать свой собственный класс аннотации данных? Как бы выглядел такой класс?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
987
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете написать свой собственный ValidationAttribute:

public class BriefingTimeRequiredAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var model = (MyModel)validationContext.ObjectInstance;
        if (model.Briefing && !model.BriefingTime.HasValue)
        {
            return new ValidationResult("BriefingTime is required.");
        }
        return ValidationResult.Success;
    }
}

Откуда у этого класса Briefing и BriefingTime?

Robert Harvey 30.10.2018 22:23

Предполагается, что @RobertHarvey MyModel является моделью, в которой вы определили эти значения, по внешнему виду. Это атрибут, написанный для обработки только проверки одного свойства, а не универсальный валидатор для любого свойства, зависящего от другого свойства.

Servy 30.10.2018 22:25

@Servy: Значит, model.BriefingTime?

Robert Harvey 30.10.2018 22:26

@ Роберт Харви Ага.

Servy 30.10.2018 22:27
ValidationContext равен нулю.
Robert Harvey 30.10.2018 22:42

Можете ли вы опубликовать полный образец кода, включая модель?

mr.coffee 30.10.2018 22:50

В моей ViewModel много кода, но единственные два важных свойства - это Briefing и BriefingTime. BriefingTime теперь украшен [BriefingTimeRequired]. Метод ValidationResult срабатывает правильно, но в ValidationContext ничего нет.

Robert Harvey 30.10.2018 22:53

Попробуйте переопределить это свойство: public override bool RequiresValidationContext { get { return true; } } в своем пользовательском классе атрибутов проверки.

mr.coffee 30.10.2018 23:00

По-прежнему нулевой. Я думаю, что это конкретное переопределение IsValid делает некоторые предположения о том, как работает жизненный цикл страницы ASP.NET, предположения, которые недопустимы в WPF.

Robert Harvey 30.10.2018 23:52

@RobertHarvey Пожалуйста, покажите нам свой код для проверки. Вы реализовали IDataErrorInfo или INotifyDataErrorInfo

Sir Rufo 31.10.2018 02:08

@SirRufo: INotifyDataErrorInfo. По сути, это эта реализация, Кроме, что я проверяю всю форму только при нажатии кнопки «Сохранить», а не при изменении отдельных свойств. Он отлично работает с атрибутом [Required]. Мой класс ViewModel унаследован от AnnotationValidationViewModel.

Robert Harvey 31.10.2018 03:37

@RobertHarvey Да, конечно, RequiredAttribute работает, потому что ему не нужен ValidationContext. Реализация важна, потому что теперь мы видим, что вы вызываете метод ValidationAttribute.IsValid без ValidationContext.

Sir Rufo 31.10.2018 07:25

@SirRufo: IsValid() не имеет перегрузки, которая принимает ValidationContext в качестве параметра, но я понимаю вашу точку зрения. Я изменил реализацию на новый объект ValidationContext и вызвал Validate() для атрибута, если для RequiresValidationContext задано значение true, и теперь, похоже, он работает. Спасибо.

Robert Harvey 31.10.2018 15:49

@RobertHarvey Документация рассказывает нам другую историю. Пожалуйста, нажмите эта ссылка и прочтите. Вы должны увидеть IsValid (объект, ValidationContext) (аргументы два, второй - ValidationContext, а имя метода - Является действительным) - и посмотрите на код этого ответа - это метод отменяет IsValid

Sir Rufo 31.10.2018 16:41

@SirRufo: Эта перегрузка недоступна мне в AnnotationValidationViewModel, моей реализации INotifyDataErrorInfo, потому что она помечена как protected. (AnnotationValidationViewModel не наследуется от ValidationAttribute, и не должен.)

Robert Harvey 31.10.2018 17:19

@RobertHarvey Вы должны проверить с помощью статического класса Валидатор. Это способ вызвать этот защищенный метод IsValid

Sir Rufo 31.10.2018 18:20

@SirRufo: Спасибо, я посмотрю.

Robert Harvey 31.10.2018 18:27

Другие вопросы по теме