diff --git a/samples/BlazorServer/Pages/Index.razor b/samples/BlazorServer/Pages/Index.razor
index f227a9f..4cc349e 100644
--- a/samples/BlazorServer/Pages/Index.razor
+++ b/samples/BlazorServer/Pages/Index.razor
@@ -68,6 +68,7 @@
+
@code {
private readonly Person _person = new();
@@ -78,4 +79,14 @@
private void PartialValidate()
=> Console.WriteLine($"Partial validation result : {_fluentValidationValidator?.Validate(options => options.IncludeRuleSets("Names"))}");
+
+ private void AddValidationResult()
+ {
+ _fluentValidationValidator!.AddValidationResult(_person, new FluentValidation.Results.ValidationResult
+ {
+ Errors = new List {
+ new FluentValidation.Results.ValidationFailure { PropertyName = "EmailAddress", ErrorMessage = "This email address is taken already"}
+ }
+ });
+ }
}
\ No newline at end of file
diff --git a/samples/BlazorWebAssembly/Pages/Index.razor b/samples/BlazorWebAssembly/Pages/Index.razor
index 400e083..367024f 100644
--- a/samples/BlazorWebAssembly/Pages/Index.razor
+++ b/samples/BlazorWebAssembly/Pages/Index.razor
@@ -68,6 +68,7 @@
+
@code {
private readonly Person _person = new();
@@ -83,4 +84,14 @@
private void PartialValidate()
=> Console.WriteLine($"Partial validation result : {_fluentValidationValidator?.Validate(options => options.IncludeRuleSets("Names"))}");
+
+ private void AddValidationResult()
+ {
+ _fluentValidationValidator!.AddValidationResult(_person, new FluentValidation.Results.ValidationResult
+ {
+ Errors = new List {
+ new FluentValidation.Results.ValidationFailure { PropertyName = "EmailAddress", ErrorMessage = "This email address is taken already"}
+ }
+ });
+ }
}
\ No newline at end of file
diff --git a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs
index c06c9f4..5477e08 100644
--- a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs
+++ b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs
@@ -17,17 +17,14 @@ public static void AddFluentValidation(this EditContext editContext, IServicePro
{
ArgumentNullException.ThrowIfNull(editContext, nameof(editContext));
- var messages = new ValidationMessageStore(editContext);
-
editContext.OnValidationRequested +=
- async (sender, _) => await ValidateModel((EditContext)sender!, messages, serviceProvider, disableAssemblyScanning, fluentValidationValidator, validator);
+ async (sender, _) => await ValidateModel((EditContext)sender!, serviceProvider, disableAssemblyScanning, fluentValidationValidator, validator);
editContext.OnFieldChanged +=
- async (_, eventArgs) => await ValidateField(editContext, messages, eventArgs.FieldIdentifier, serviceProvider, disableAssemblyScanning, validator);
+ async (_, eventArgs) => await ValidateField(editContext, fluentValidationValidator.Messages, eventArgs.FieldIdentifier, serviceProvider, disableAssemblyScanning, validator);
}
private static async Task ValidateModel(EditContext editContext,
- ValidationMessageStore messages,
IServiceProvider serviceProvider,
bool disableAssemblyScanning,
FluentValidationValidator fluentValidationValidator,
@@ -56,11 +53,11 @@ private static async Task ValidateModel(EditContext editContext,
editContext.Properties[PendingAsyncValidation] = asyncValidationTask;
var validationResults = await asyncValidationTask;
- messages.Clear();
+ fluentValidationValidator.Messages.Clear();
foreach (var validationResult in validationResults.Errors)
{
var fieldIdentifier = ToFieldIdentifier(editContext, validationResult.PropertyName);
- messages.Add(fieldIdentifier, validationResult.ErrorMessage);
+ fluentValidationValidator.Messages.Add(fieldIdentifier, validationResult.ErrorMessage);
}
editContext.NotifyValidationStateChanged();
diff --git a/src/Blazored.FluentValidation/FluentValidationsValidator.cs b/src/Blazored.FluentValidation/FluentValidationsValidator.cs
index ae8e6f9..117d300 100644
--- a/src/Blazored.FluentValidation/FluentValidationsValidator.cs
+++ b/src/Blazored.FluentValidation/FluentValidationsValidator.cs
@@ -18,6 +18,8 @@ public class FluentValidationValidator : ComponentBase
[Parameter] public Action>? Options { get; set; }
internal Action>? ValidateOptions { get; set; }
+ internal ValidationMessageStore Messages { get; private set; }
+
public bool Validate(Action>? options = null)
{
if (CurrentEditContext is null)
@@ -79,6 +81,30 @@ protected override void OnInitialized()
$"inside an {nameof(EditForm)}.");
}
+ Messages = new ValidationMessageStore(CurrentEditContext);
CurrentEditContext.AddFluentValidation(ServiceProvider, DisableAssemblyScanning, Validator, this);
}
+
+ ///
+ /// Adds the validation errors contained in a FluentValidation ValidationResult object to the
+ /// current EditContext's validation messages. This allows for manual validation scenarios where
+ /// the ValidationResult may not be automatically integrated into Blazor's validation system.
+ /// Calling this method will update the validation state and the associated UI elements.
+ ///
+ /// The object instance that the validation applies to. This is used to
+ /// identify the form model within the EditContext.
+ /// The ValidationResult obtained from FluentValidation that contains
+ /// the details of any validation errors.
+ public void AddValidationResult(object model, ValidationResult validationResult)
+ {
+ if (CurrentEditContext != null && Messages != null)
+ {
+ foreach (ValidationFailure error in validationResult.Errors)
+ {
+ var fieldIdentifier = new FieldIdentifier(model, error.PropertyName);
+ Messages.Add(fieldIdentifier, error.ErrorMessage);
+ }
+ CurrentEditContext.NotifyValidationStateChanged();
+ }
+ }
}
\ No newline at end of file