I have an array of objects I am receiving in an HTTP Post body. Looks something like this:
{
load: {
stops: [
{
Name: "Stop 1",
AppointmentDateTime: "02/25/2025T14:00:00"
},
{
Name: "Stop 2",
AppointmentDateTime: "02/25/2025T13:00:00"
},
{
Name: "Stop 3",
AppointmentDateTime: "02/25/2025T15:30:00"
}
]
}
}
I have already got a fluid validator in C# working with some of the following code:
RuleForEach(x => x.Stops).ChildRule(stop =>
{
stop.RuleFor(s => s.Name).NotEmpty().NotNull();
stop.RuleFor(s => s.AppointmentDateTime).NotEmpty().NotNull().Must(x => x > x.DateTime.Now).WithMessage("AppointmentDateTime must be in the future");
}
While this works, I would like to validate that the items in the array are after each other. Stop 2 should have an appointment time after stop 1 and stop 3 after stop 2 etc. I can't find a way in the code to do something like a for loop where I can save the previous item value. Ideally I was going to do something like:
Stop? prevStop = null;
foreach (stop in stops) {
if (!prevStop is null)
{
DO SOMETHING TO validate that prevStop.AppointmentDateTime > stop.AppointmentDateTime;
}
prevStop = stop;
}
While there is a foreach like way of testing the items, I don't see a way to save the previous item for comparison to the current one.
you can create Custom Validator as follows :
public class LoadValidator : AbstractValidator<Load>
{
public LoadValidator()
{
RuleForEach(x => x.Stops).ChildRule(stop =>
{
stop.RuleFor(s => s.Name).NotEmpty().NotNull();
stop.RuleFor(s => s.AppointmentDateTime).NotEmpty().NotNull().Must(x => x > DateTime.Now).WithMessage("AppointmentDateTime must be in the future");
});
RuleFor(x => x.Stops).Must(stops => BeInChronologicalOrder(stops)).WithMessage("Stops must be in chronological order");
}
private bool BeInChronologicalOrder(Stop[] stops)
{
if (stops == null || stops.Length <= 1)
{
return true;
}
//iterate through the array
//and compare the AppointmentDateTime of the current stop
//with the AppointmentDateTime of the previous stop.
//If any stop's appointment time
//is not after the previous stop's appointment time, the validation fails,
//and the method returns false.
for (int i = 1; i < stops.Length; i++)
{
if (stops[i].AppointmentDateTime <= stops[i - 1].AppointmentDateTime)
{
return false;
}
}
return true;
}
}