FluentValidation - валидиране в множество свойства

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

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 (комбинирани свойства за дата+час), но не съм сигурен как да го направя.

Редактиране: За да поясня, трябва по някакъв начин да комбинирам EndDate + EndTime/StartDate + StartTime, т.е. DateTime.Parse(src.StartDate + " " + src.StartTime) и след това да валидирам EndDateTime спрямо StartDateTime - как да Правя го?


person seekay    schedule 09.10.2011    source източник


Отговори (2)


Най-накрая проработи, след като прочетох отново документацията: "Имайте предвид, че има е допълнително претоварване за 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);
        }
    }

Може да има по-изчистен/по-елегантен начин да направите това, но засега той работи.

person seekay    schedule 10.10.2011
comment
Възможно ли е да се направи същата клиентска страна? - person SMC; 09.08.2013
comment
Това вече не е валидно във FluentValitation. Това е правилният отговор: stackoverflow.com/a/20546097/59119 - person Natrium; 31.08.2016

Можете да опитате да използвате правилото GreaterThan:

RuleFor(x => x.EndDate)
    .GreaterThan(x => x.StartDate)
    .WithMessage("end date must be after start date");
person Darin Dimitrov    schedule 09.10.2011
comment
Съжаляваме, току-що добавих пояснение по-горе. Трябва да комбинирате дата + час и след това да потвърдите - person seekay; 10.10.2011
comment
Възможно ли е да се направи същата клиентска страна? или моля, проверете тук stackoverflow.com/questions/18142489/ - person SMC; 09.08.2013