Misiu
Misiu

Reputation: 4919

FluentValidation modify error message in Must function

Inside class that is responsible for validation I have simple rule:

RuleFor(u => u.Id)
    .Cascade(CascadeMode.StopOnFirstFailure)
    .NotEmpty().WithMessage("Id is required")
    .Must(ValidateId);

and below is my ValidateId function:

private bool ValidateId(CreateAccountBindingModel model, string id, PropertyValidatorContext context)
{
    if (id=="test")
    {
        context.Rule.CurrentValidator.ErrorCodeSource = new StaticStringSource("You are testing");
        return false;
    }

    var idValid = IdValidator.IsValid(id);
    if (!idValid)
    {
        context.Rule.CurrentValidator.ErrorCodeSource = new StaticStringSource("Id is invalid");
        return false;
    }
    return true;
}

If I run my validator I get default error, not my custom errors I'm specifying inside my function.
I've tried setting them using:

context.Rule.CurrentValidator.ErrorCodeSource = new StaticStringSource("Id is invalid");

but without any luck.

How can I define error message inside validation function?

Upvotes: 15

Views: 14146

Answers (3)

EbergOne
EbergOne

Reputation: 1

You can do this

RuleFor(u => u.Id)
  .Cascade(CascadeMode.StopOnFirstFailure)
  .NotEmpty().WithMessage("Id is required")
  .Must((u, id, context) =>
  {
    if (id == "test")
    {
      context.MessageFormatter.AppendArgument("errorText", "You are testing");

      return false;
    }

    var idValid = IdValidator.IsValid(id);
    if (!idValid)
    {
      context.MessageFormatter.AppendArgument("errorText", $"Id is invalid");

      return false;
    }

    return true;
  }).WithMessage(x => "{errorText}");
            

Upvotes: 0

tarn
tarn

Reputation: 372

You can use CustomValidator instead:

RuleFor(u => u.Id)
    .Cascade(CascadeMode.StopOnFirstFailure)
    .NotEmpty().WithMessage("Id is required")
    .Custom(ValidateId);

And below - ValidateId method:

private void ValidateId(string id, CustomContext context)
{
    if (id == "test")
    {
         context.AddFailure("You are testing");
    }
    var idValid = IdValidator.IsValid(id);
    if (!idValid)
    {
        context.AddFailure("Id is invalid");
    }
}

Upvotes: 13

toadflakz
toadflakz

Reputation: 7944

I wouldn't implement what you are trying to do with a custom validation function as you can do it using FluentValidation itself:

RuleFor(u => u.Id)
 .Cascade(CascadeMode.StopOnFirstFailure)
 .Must(x => x !="test").WithMessage("You are testing.")
 .Must(x => IdValidator.IsValid(x)).WithMessage("Id is invalid.");

Upvotes: 1

Related Questions