FluentValidation - проверка по нескольким свойствам - PullRequest
31 голосов
/ 09 октября 2011

Иметь форму, в которой пользователь может ввести дату / время начала и дату / время окончания для события.Вот такой валидатор:

public class EventModelValidator : AbstractValidator<EventViewModel>
    {
        public EventModelValidator()
        {
            RuleFor(x => x.StartDate)
                .NotEmpty().WithMessage("Date is required!")
                .Must(BeAValidDate).WithMessage("Invalid date");
            RuleFor(x => x.StartTime)
                .NotEmpty().WithMessage("Start time is required!")
                .Must(BeAValidTime).WithMessage("Invalid Start time");
            RuleFor(x => x.EndTime)
                .NotEmpty().WithMessage("End time is required!")
                .Must(BeAValidTime).WithMessage("Invalid End time");
            RuleFor(x => x.Title).NotEmpty().WithMessage("A title is required!");
        }


        private bool BeAValidDate(string value)
        {
            DateTime date;
            return DateTime.TryParse(value, out date);
        }

        private bool BeAValidTime(string value)
        {
            DateTimeOffset offset;
            return DateTimeOffset.TryParse(value, out offset);
        }

    }

Теперь я также хотел бы добавить подтверждение того, что EndDateTime> StartDateTime (объединенные свойства Date + Time), но не уверен, как это сделать.

Редактировать: Чтобы уточнить, мне нужно как-то объединить EndDate + EndTime / StartDate + StartTime, т.е. DateTime.Parse (src.StartDate + "" + src.StartTime), а затем проверить EndDateTime против StartDateTime - какЯ так делаю?

Ответы [ 2 ]

38 голосов
/ 11 октября 2011

Наконец-то он заработал после того, как я перечитал документацию : "Обратите внимание, что существует дополнительная перегрузка для Must, которая также принимает проверяемый экземпляр родительского объекта."

public class EventModelValidator : AbstractValidator<EventViewModel>
    {
        public EventModelValidator()
        {
            RuleFor(x => x.StartDate)
                .NotEmpty().WithMessage("Date is required!")
                .Must(BeAValidDate).WithMessage("Invalid date");
            RuleFor(x => x.StartTime)
                .NotEmpty().WithMessage("Start time is required!")
                .Must(BeAValidTime).WithMessage("Invalid Start time");
            RuleFor(x => x.EndTime)
                .NotEmpty().WithMessage("End time is required!")
                .Must(BeAValidTime).WithMessage("Invalid End time")
                // new
                .Must(BeGreaterThan).WithMessage("End time needs to be greater than start time");
            RuleFor(x => x.Title).NotEmpty().WithMessage("A title is required!");
        }


        private bool BeAValidDate(string value)
        {
            DateTime date;
            return DateTime.TryParse(value, out date);
        }

        private bool BeAValidTime(string value)
        {
            DateTimeOffset offset;
            return DateTimeOffset.TryParse(value, out offset);
        }
        // new
        private bool BeGreaterThan(EventViewModel instance, string endTime)
        {
            DateTime start = DateTime.Parse(instance.StartDate + " " + instance.StartTime);
            DateTime end = DateTime.Parse(instance.EndDate + " " + instance.EndTime);
            return (DateTime.Compare(start, end) <= 0);
        }
    }

Возможно, есть более чистый / более легкомысленный способ сделать это, но на данный момент он работает формально.

15 голосов
/ 09 октября 2011

Вы можете попробовать использовать правило GreaterThan:

RuleFor(x => x.EndDate)
    .GreaterThan(x => x.StartDate)
    .WithMessage("end date must be after start date");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...