1

I am using FluentValidation for the server side validation. Now I want to call a function using must.

This is the form code snippet :

<form method="post"
      asp-controller="Category"
      asp-action="SaveSpecification"
      role="form"
      data-ajax="true"
      data-ajax-loading="#Progress"
      data-ajax-success="Specification_JsMethod">
  <input asp-for="Caption" class="form-control" />
  <input type="hidden" asp-for="CategoryId" />
  <button class="btn btn-primary" type="submit"></button>                                      
</form>

What changes should I make to the code below to call function SpecificationMustBeUnique ?

public class SpecificationValidator : AbstractValidator<Specification>
{
    public SpecificationValidator()
    {
        RuleFor(x => new { x.CategoryId, x.Caption}).Must(x => SpecificationMustBeUnique(x.CategoryId, x.Caption)).WithMessage("not unique");
    }

    private bool SpecificationMustBeUnique(int categoryId, string caption)
    {
        return true / false;
    }
} 

Tips: 1 - The combination of CategoyId and Caption should be unique 2 - Validation is not done when submitting the form(the validation just not running when submit the form)

farshid azizi
  • 364
  • 1
  • 5
  • 18
  • 1
    Is the combination of CategoryId and Caption supposed to be unique? Are you getting an exception or compiler error? Is the validation just not running when you submit the form? It is unclear what problem you need solved. – Greg Burghardt Aug 21 '19 at 12:40
  • See [Predicate Validator](https://fluentvalidation.net/built-in-validators#predicate-validator) in the official documentation. – Greg Burghardt Aug 21 '19 at 12:42
  • 1
    Tips: 1 - The combination of CategoyId and Caption should be unique 2 - Validation is not done when submitting the form – farshid azizi Aug 21 '19 at 12:47

1 Answers1

2

The tricky part is deciding which property should be validated when the validation rule applies to a combination of values on different fields. I usually just close my eyes, and point to one of the view model properties and say "this is the property I'll attach the validator to." With very little thought. FluentValidation works best when the validation rules apply to a single property, so it knows which property will display the validation message.

So, just pick CategoryId or Caption and attach the validator to it:

RuleFor(x => x.CategoryId)
    .Must(BeUniqueCategoryAndCaption)
        .WithMessage("{PropertyName} and Caption must be unique.");

The signature for the BeUniqueCategoryAndCaption method would look like:

private bool BeUniqueCategoryAndCaption(Specification model, int categoryId)
{
    return true / false;
}

Note: I guessed that the CategoryId property is an int, but you will need to make sure the categoryId argument to BeUniqueCategoryAndCaption is the same type as the CategoryId property in your view model.

Greg Burghardt
  • 17,900
  • 9
  • 49
  • 92
  • However, BeUniqueCategoryAndCaption does not run! but, values ​​(cpation and categoryId) are passed to the model – farshid azizi Aug 21 '19 at 13:59
  • @farshidazizi: Are you using `RuleFor(x => x.CategoryId)` in your FluentValidation class? If you are, please post the code in your controller, and how you are integrating FluentValidation with the web framework (MVC, WebForms, etc.). – Greg Burghardt Aug 21 '19 at 14:01
  • @ GregBurghardt : yes im using RuleFor(x => x.CategoryId) in my FluentValidation class/ and using mvc core – farshid azizi Aug 21 '19 at 14:09
  • @farshidazizi: Are there any other FluentValidation rules running, and only this one is not? Please post the code in your controller, and the code that configured MVC Core to use FluentValidation. Also, please post how you are associating the `Specification` view model with the validator. At this point it feels like the "glue" between the MVC framework and FluentValidation isn't working properly. – Greg Burghardt Aug 21 '19 at 14:12