Home > database >  Weird error when using Fluent Validation API and Mud Blazor
Weird error when using Fluent Validation API and Mud Blazor

Time:08-19

Using Fluent validation for some NotEqual rules for some of our models and getting an odd error when the validation should succeed. Our model has a couple of fields that are all complex user models. They cannot be the same as each other. When they are the same, fluent validator works correctly and displays my custom error message. When they aren't the same, no error text should show however, this is what I see:

.Email

Doesn't really make sense. Any idea what is happening?

validator class:

using FluentValidation;
using Data.Models.DBModels;

namespace Compyl.WebApp.Validators
{
    public class AssessmentModelFluentValidator : AbstractValidator<AssessmentModel>
    {
        public AssessmentModelFluentValidator()
        {
            RuleLevelCascadeMode = CascadeMode.Stop;
           
            
            RuleFor(x => x.Owner)
           
                .NotEqual(x=> x.DelegateOwner)
                .WithMessage("Owner cannot be the same as Delegate Owner")
                .NotEqual(X => X.Reviewer)
                .WithMessage("Owner cannot be the same as Reviewer");

            RuleFor(x => x.DelegateOwner)       
                .NotEqual(x => x.Owner)
                .WithMessage("Delegate Owner cannot be the same as Owner")
                .NotEqual(X => X.Reviewer)
                .WithMessage("Delegate Owner cannot be the same as Reviwer");



            RuleFor(x => x.Reviewer)
      
                .NotEqual(x => x.Owner)
                .WithMessage("Reviewer cannot be the same as Owner")
                .NotEqual(X => X.DelegateOwner)
                .WithMessage("Reviewer cannot be the same as Delegate Owner");


        }

        public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>
        {
            var result = await ValidateAsync(ValidationContext<AssessmentModel>.CreateWithOptions((AssessmentModel)model, x => x.IncludeProperties(propertyName)));
            if (result.IsValid)
                return Array.Empty<string>();
            return result.Errors.Select(e => e.ErrorMessage);
        };
    }
}

part of the form:


<MudForm  @ref="form" Model="@assessment" @bind-IsValid="@success"  Validation="@(assessmentValidator.ValidateValue)" @bind-Errors="@errors">
  <MudCard Elevation="0">
     <MudCardHeader>
         <CardHeaderContent>
             <MudText Typo="Typo.h6">@assessment.Name</MudText>
              <MudText>@assessment.Description</MudText>
          </CardHeaderContent>
                    
       </MudCardHeader>
       <MudCardContent>
        <MudTabs Elevation="2" Rounded="true" ApplyEffectsToContainer="true" PanelClass="pa-6">
            <MudTabPanel Text="Assessment Details">
                  <MudTextField  Immediate="true" For="@(() => assessment.Name)"  Variant="Variant.Outlined" Disabled="@(!canEdit)" RequiredError="Assessment Name is Required!"  Required Label="Name" @bind-Value="assessment.Name" />
                   <MudTextField  For="@(() => assessment.Description)"  Variant="Variant.Outlined"  Disabled="@(!canEdit)" Lines="4" Label="Description" @bind-Value="assessment.Description" />
                   <MudAutocomplete   Immediate="true" For="@(() => assessment.Owner)" Variant="Variant.Outlined"  Disabled="@(!canEdit)" T="UserModel"  @bind-Value="assessment.Owner" RequiredError="Assessment Owner is Required!" Required Label="Owner"   ToStringFunc="@(e=> e==null? null : $"{e.Email}")" SearchFunc="@SearchUsers" />
                 <MudAutocomplete  Immediate="true" For="@(() => assessment.DelegateOwner)" Variant="Variant.Outlined" Disabled="@(!canEdit)" T="UserModel"  @bind-Value="assessment.DelegateOwner" Label="Delegate Owner" ToStringFunc="@(e=> e==null? null : $"{e.Email}")" SearchFunc="@SearchUsers" />
                  <MudAutocomplete  Immediate="true" For="@(() => assessment.Reviewer)" Variant="Variant.Outlined" Disabled="@(!canEdit)" T="UserModel" @bind-Value="assessment.Reviewer" RequiredError="Assessment Reviewer is Required!" Required Label="Reviewer"  ToStringFunc="@(e=> e==null? null : $"{e.Email}")" SearchFunc="@SearchUsers" />

CodePudding user response:

You cannot compare objects with Fluent Validation. You have to compare individual properties. In this case it would make sense to compare an ID (I'm guessing at the property names)

RuleFor(x => x.Reviewer.Id)
    .NotEqual(x => x.Owner.Id)
    .WithMessage("Reviewer cannot be the same as Owner")
    .NotEqual(X => X.DelegateOwner.Id)
    .WithMessage("Reviewer cannot be the same as Delegate Owner");

CodePudding user response:

It's partly Bron's answer in the comment, but also with the MudBlazor's "For" not working with complex objects either. Workaround is to bind the ID of the complex model to the field, instead of the full model. This way you can set the rule and the for statement for the ID instead.

  • Related