Blazored / FluentValidation

A library for using FluentValidation with Blazor
https://blazored.github.io/FluentValidation/
MIT License
597 stars 85 forks source link

[Bug] #206

Open saitoreeper opened 11 months ago

saitoreeper commented 11 months ago

Describe the bug I have a form with sub components on the form that is loaded as a wizzard. The validation trigger on the first page/component and the red error appears under the field.

On the next tab it doesn't highlight the error as red, I am extremely confused at this point why it is happening. I can see there is errors because of my foreach at the top of every tab

To Reproduce Main Page CSHTML ` @ @

@if (ValidationResult.Errors.Count > 0) {
Advert Type
}
Advert Type
@if (ValidationResult.Errors.Count > 0) {
Advert Type
}
@if (ValidationResult.Errors.Count > 0) {
Advert Type
}
` **Main Page .cs responsible for the navigation** ` **This method that triggers the first navigate works and highlight the error in the subcomponent** private async void ContinueToPropertyDescriptionPage() { if (PropertyRequest.PropertyAddressRequest == null) { PropertyRequest.PropertyAddressRequest = new PropertyAddressRequest(); } var validationResult = await AgencyAddressCreateValidator.ValidateAsync(PropertyRequest); if (validationResult.IsValid) { DescriptionPage = false; SelectedPage = 1; } else { // Update the EditContext to trigger validation messages editContext.NotifyValidationStateChanged(); // Handle validation errors, you can access them using validationResult.Errors foreach (var error in validationResult.Errors) { Console.WriteLine($"Property: {error.PropertyName}, Error: {error.ErrorMessage}"); } } } **This form trigger doesn't trigger sub component errors** private async void ContinueToPropertyListingTypePage() { if (AdvertTypeId == 1 && IsPrivate == false) { ValidationResult = await AgencyDescriptionValidator.ValidateAsync(PropertyRequest); } else if (AdvertTypeId == 1 && IsPrivate == true) { ValidationResult = await PrivateDescriptionValidator.ValidateAsync(PropertyRequest); } else if (AdvertTypeId == 2 && IsPrivate == false) { ValidationResult = await AgencyToRentDescriptionValidator.ValidateAsync(PropertyRequest); } else if (AdvertTypeId == 2 && IsPrivate == true) { ValidationResult = await PrivateToRentListingTypeValidator.ValidateAsync(PropertyRequest); } if (ValidationResult.IsValid) { ListingTypePage = false; SelectedPage = 2; } else { // Update the EditContext to trigger validation messages editContext.NotifyValidationStateChanged(); // Handle validation errors, you can access them using validationResult.Errors foreach (var error in ValidationResult.Errors) { Console.WriteLine($"Property: {error.PropertyName}, Error: {error.ErrorMessage}"); } } } ` **_SubComponents_** **Address** `@using Syncfusion.Blazor.Buttons
Address
@*
*@ @*
*@
Hide Address
` **PropertyDescription (error doesn not trigger)** `@using Blazored.FluentValidation @using Syncfusion.Blazor.Navigations @using Syncfusion.Blazor.DropDowns @* @using Syncfusion.Blazor.Calendars @using Syncfusion.Blazor.Grids *@ @using Syncfusion.Blazor.Inputs @using Syncfusion.Blazor.Popups @using Syncfusion.Blazor.Buttons @using GrpcProto.PropertyMain;
Property Title
@* *@
` **_Validation Contextes_** **AgencyAddressValidator** `using BlazorWasmGrpcWithAuth0.Client.ValidationModels; using FluentValidation; using GrpcProto.PropertyMain; using System; namespace BlazorWasmGrpcWithAuth0.Client.Pages.Property.Validators.ForSale.Agency { public class AgencyAddressValidator : AbstractValidator { public AgencyAddressValidator() { RuleFor(x => x.PropertyAddressRequest.StreetNumber).NotEmpty() .NotNull().WithMessage("Address Needs to be filled in."); } } } ` **AgencyDescriptionValidator** `using BlazorWasmGrpcWithAuth0.Client.ValidationModels; using FluentValidation; using GrpcProto.PropertyMain; using System; namespace BlazorWasmGrpcWithAuth0.Client.Pages.Property.Validators.ForSale.Agency { public class AgencyDescriptionValidator : AbstractValidator { public AgencyDescriptionValidator() { RuleFor(x => x.PropertyTitle) .NotEmpty().WithMessage("Property Title needs to be filled in."); RuleFor(x => x.Description) .NotEmpty().WithMessage("Property Description cannot be empty."); RuleFor(x => x.PropertyDetailsRequest.PropertySize) .NotEmpty().WithMessage("Property Size cannot be empty."); RuleFor(x => x.PropertyDetailsRequest.FloorSize) .NotEmpty().WithMessage("Floor Size cannot be empty."); RuleFor(x => x.PropertyDetailsRequest.BedroomsCount) .NotEmpty().WithMessage("Bedrooms Count cannot be 0 or less."); RuleFor(x => x.PropertyDetailsRequest.BathroomsCount) .GreaterThanOrEqualTo(0).WithMessage("Bathrooms Count cannot be 0 or less."); RuleFor(x => x.PropertyDetailsRequest.GaragesCount) .GreaterThanOrEqualTo(0).WithMessage("Garages Count cannot be 0 or less."); RuleFor(x => x.PropertyDetailsRequest.ParkingCount) .GreaterThanOrEqualTo(0).WithMessage("Parking Count cannot be 0 or less."); } } } `