diff --git a/Demo.Forms/Models/NestedForm.cs b/Demo.Forms/Models/NestedForm.cs index 1c1b6f6..bf4cd54 100644 --- a/Demo.Forms/Models/NestedForm.cs +++ b/Demo.Forms/Models/NestedForm.cs @@ -13,6 +13,14 @@ public class NestedForm public List SubArray { set; get; } public MustNotValidate NotAForm { set; get; } + + public void Clear() + { + Email = String.Empty; + Child = new ChildForm(); + SubArray = new List { new ChildForm { }, new ChildForm { } }; + NotAForm = new MustNotValidate(); + } } public class ChildForm diff --git a/Demo/Pages/Index.razor b/Demo/Pages/Index.razor index 0c28e05..f32beda 100644 --- a/Demo/Pages/Index.razor +++ b/Demo/Pages/Index.razor @@ -19,7 +19,7 @@

Form 2: Dependency Injection Validation

- +
@@ -54,6 +54,9 @@
+

Submitting / Editing This Form Will Crash The App

@@ -85,4 +88,13 @@ }; CrashForm CrashForm = new CrashForm(); + + FluentValidator Form2FluentValidator; + + void ClearForm2() + { + Form2.Clear(); + Form2FluentValidator.ClearMessages(); + } + } diff --git a/FluentValidation.Blazor/Accelist.FluentValidation.Blazor.csproj b/FluentValidation.Blazor/Accelist.FluentValidation.Blazor.csproj index 0ea10fb..d2c71db 100644 --- a/FluentValidation.Blazor/Accelist.FluentValidation.Blazor.csproj +++ b/FluentValidation.Blazor/Accelist.FluentValidation.Blazor.csproj @@ -32,6 +32,7 @@ Version 5.0.0 BREAKING CHANGES: - Package sub-dependency Microsoft.AspNetCore.Components.Web is changed to Microsoft.AspNetCore.Components.Forms to allow using the library in Xamarin Blazor project! - Package is now compatible with both .NET 5.0 and .NET Core 3.1 + ClearableFluentValidation.Blazor diff --git a/FluentValidation.Blazor/FluentValidator.cs b/FluentValidation.Blazor/FluentValidator.cs index 8deafbe..cd7cde3 100644 --- a/FluentValidation.Blazor/FluentValidator.cs +++ b/FluentValidation.Blazor/FluentValidator.cs @@ -43,6 +43,11 @@ public class FluentValidator : ComponentBase, IDisposable [Parameter] public Dictionary ChildValidators { set; get; } = new Dictionary(); + /// + /// that gathers all validation messages linked to . + /// + protected ValidationMessageStore MessageStore { get; set; } + /// /// Attach to parent EditForm context enabling validation. /// @@ -57,6 +62,8 @@ protected override void OnInitialized() this.ServiceScope = ServiceProvider.CreateScope(); + MessageStore = new ValidationMessageStore(CurrentEditContext); + if (this.Validator == null) { this.SetFormValidator(); @@ -65,6 +72,16 @@ protected override void OnInitialized() this.AddValidation(); } + /// + /// Clear all validation messages. + /// + public void ClearMessages() + { + MessageStore.Clear(); + CurrentEditContext.MarkAsUnmodified(); + CurrentEditContext.NotifyValidationStateChanged(); + } + /// /// Try setting the EditContext form model typed validator implementation from the DI. /// @@ -122,15 +139,14 @@ private IValidationContext CreateValidationContext(object model, IValidatorSelec /// private void AddValidation() { - var messages = new ValidationMessageStore(CurrentEditContext); // Perform object-level validation on request CurrentEditContext.OnValidationRequested += - (sender, eventArgs) => ValidateModel((EditContext)sender, messages); + (sender, eventArgs) => ValidateModel((EditContext)sender); // Perform per-field validation on each field edit CurrentEditContext.OnFieldChanged += - (sender, eventArgs) => ValidateField(CurrentEditContext, messages, eventArgs.FieldIdentifier); + (sender, eventArgs) => ValidateField(CurrentEditContext, eventArgs.FieldIdentifier); } /// @@ -138,12 +154,12 @@ private void AddValidation() /// /// /// - private async void ValidateModel(EditContext editContext, ValidationMessageStore messages) + private async void ValidateModel(EditContext editContext) { // should now be able to run async validations: // https://github.com/dotnet/aspnetcore/issues/11914 var validationResults = await TryValidateModel(editContext); - messages.Clear(); + MessageStore.Clear(); var graph = new ModelGraphCache(editContext.Model); foreach (var error in validationResults.Errors) @@ -153,7 +169,7 @@ private async void ValidateModel(EditContext editContext, ValidationMessageStore if (propertyValue != null) { var fieldID = new FieldIdentifier(propertyValue, propertyName); - messages.Add(fieldID, error.ErrorMessage); + MessageStore.Add(fieldID, error.ErrorMessage); } } @@ -238,7 +254,7 @@ private IValidator TryGetFieldValidator(EditContext editContext, in FieldIdentif /// /// /// - private async void ValidateField(EditContext editContext, ValidationMessageStore messages, FieldIdentifier fieldIdentifier) + private async void ValidateField(EditContext editContext, FieldIdentifier fieldIdentifier) { var fieldValidator = TryGetFieldValidator(editContext, fieldIdentifier); if (fieldValidator == null) @@ -248,11 +264,11 @@ private async void ValidateField(EditContext editContext, ValidationMessageStore } var validationResults = await TryValidateField(fieldValidator, editContext, fieldIdentifier); - messages.Clear(fieldIdentifier); + MessageStore.Clear(fieldIdentifier); foreach (var error in validationResults.Errors) { - messages.Add(fieldIdentifier, error.ErrorMessage); + MessageStore.Add(fieldIdentifier, error.ErrorMessage); } editContext.NotifyValidationStateChanged(); @@ -277,6 +293,7 @@ protected virtual void Dispose(bool disposing) ServiceScope = null; Validator = null; ChildValidators = null; + MessageStore = null; disposedValue = true; }