1

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.

1 Answer 1

1

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;
    }
}

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that got me further, but the line RuleFor(x => x.Stops).Must(BeInChronologicalOrder).WithMessage("Stops must be in chronological order"); } says that it cannot convert from 'method group' to 'System.Func....'
I figured it out. I will edit the code above to fix it so it works correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.