Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Dependent Rules FluentValidation

Just started using this awesome api, I am facing some issue with multiple DependentRules. I had rules like this

RuleFor(d => d.NotificationType).NotEmpty().WithMessage("Required");
When(d => d.NotificationType.ToUpper() == "EMAIL", () =>
{
    RuleFor(d => d.NotificationEmail).EmailAddress().WithMessage("Invalid Email Address");
    RuleFor(d => d.NotificationEmail).NotEmpty().WithMessage("Required");

});
When(d => d.NotificationType.ToUpper() == "SMS", () =>
{
    RuleFor(d => d.NotificationContactNo).NotEmpty().WithMessage("Required");
});

But this fails when NotificationType is Empty,it already raised the Required error. Now in this case these other rules are dependent rules and they should only execute when NotificationType is not empty. For this i have modified the rules as:

RuleFor(d => d.NotificationType).NotEmpty().WithMessage("Required").DependentRules(k =>
    k.When(d => d.NotificationType.ToUpper() == "EMAIL", () =>
    {
        RuleFor(d => d.NotificationEmail).EmailAddress().WithMessage("Invalid Email Address");
        RuleFor(d => d.NotificationEmail).NotEmpty().WithMessage("Required");
    })
);
RuleFor(d => d.NotificationType).NotEmpty().WithMessage("Required").DependentRules(k =>
    When(d => d.NotificationType.ToUpper() == "SMS", () =>
    {
        RuleFor(d => d.NotificationContactNo).NotEmpty().WithMessage("Required");
    })
);

It is working but i am repeating this rule d.NotificationType).NotEmpty(), I want to achieve something like this, Multiple Dependent Rules under one Rule.

RuleFor(d => d.NotificationType).NotEmpty().WithMessage("Required").DependentRules(k =>
    k.When(d => d.NotificationType.ToUpper() == "EMAIL", () =>
    {
        RuleFor(d => d.NotificationEmail).EmailAddress().WithMessage("Invalid Email Address");
        RuleFor(d => d.NotificationEmail).NotEmpty().WithMessage("Required");
    });
    k.When(d => d.NotificationType.ToUpper() == "SMS", () =>
    {
        RuleFor(d => d.NotificationContactNo).NotEmpty().WithMessage("Required");
    })
);

Any idea how can i achieve this ?

like image 370
Ali Umair Avatar asked Dec 19 '17 08:12

Ali Umair


3 Answers

You should set the CascadeMode on your first rule, so that the validation stops on the first failure.

RuleFor(d => d.NotificationType)
  .Cascade(CascadeMode.StopOnFirstFailure)
  .NotEmpty()
  .WithMessage("Required");
like image 141
Jehof Avatar answered Nov 15 '22 08:11

Jehof


It is not so elegant but you can avoid failure by modifying your conditions:

RuleFor(d => d.NotificationType).NotEmpty().WithMessage("Required");

When(d => !string.IsNullOrEmpty(d.NotificationType) && d.NotificationType.ToUpper() == "EMAIL", () =>
{
    RuleFor(d => d.NotificationEmail).EmailAddress().WithMessage("Invalid Email Address");
    RuleFor(d => d.NotificationEmail).NotEmpty().WithMessage("Required");

});

When(d => !string.IsNullOrEmpty(d.NotificationType) && d.NotificationType.ToUpper() == "SMS", () =>
{
    RuleFor(d => d.NotificationContactNo).NotEmpty().WithMessage("Required");
});
like image 2
Roman Koliada Avatar answered Nov 15 '22 09:11

Roman Koliada


Your solution helped me by doing something like this

RuleFor(d => d.NotificationType).NotEmpty().WithMessage("Required")
.DependentRules(k =>
    k.When(d => d.NotificationType.ToUpper() == "EMAIL", () =>
    {
        RuleFor(d => d.NotificationEmail).EmailAddress().WithMessage("Invalid Email Address");
        RuleFor(d => d.NotificationEmail).NotEmpty().WithMessage("Required");
    })
).DependentRules(k =>
    k.When(d => d.NotificationType.ToUpper() == "SMS", () =>
    {
        RuleFor(d => d.NotificationContactNo).NotEmpty().WithMessage("Required");
    }));
like image 1
Jeogan Dias Avatar answered Nov 15 '22 07:11

Jeogan Dias