|
|
@@ -0,0 +1,66 @@
|
|
|
+using FluentValidation;
|
|
|
+using FluentValidation.Internal;
|
|
|
+
|
|
|
+using Microsoft.AspNetCore.Components;
|
|
|
+using Microsoft.AspNetCore.Components.Forms;
|
|
|
+
|
|
|
+namespace BlazorEditForms;
|
|
|
+
|
|
|
+public class FluentValidationFormComponent : ComponentBase
|
|
|
+{
|
|
|
+ [CascadingParameter] EditContext? CurrentEditContext { get; set; }
|
|
|
+
|
|
|
+ [Parameter] public IValidator? Validator { get; set; }
|
|
|
+
|
|
|
+ [Inject] private IServiceProvider ServiceProvider { get; set; } = default!;
|
|
|
+
|
|
|
+ private ValidationMessageStore? _messages;
|
|
|
+
|
|
|
+ protected override void OnInitialized()
|
|
|
+ {
|
|
|
+ if (CurrentEditContext == null)
|
|
|
+ {
|
|
|
+ throw new InvalidOperationException($"{nameof(FluentValidationFormComponent)} requires a cascading parameter of type {nameof(EditContext)}");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Validator == null)
|
|
|
+ {
|
|
|
+ throw new InvalidOperationException($"{nameof(FluentValidationFormComponent)} requires a parameter of type {nameof(IValidator)}");
|
|
|
+ }
|
|
|
+
|
|
|
+ _messages = new ValidationMessageStore(CurrentEditContext);
|
|
|
+ CurrentEditContext.OnFieldChanged += CurrentEditContext_OnFieldChanged;
|
|
|
+ CurrentEditContext.OnValidationRequested += CurrentEditContext_OnValidationRequested;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private async void CurrentEditContext_OnFieldChanged(object? sender, FieldChangedEventArgs e)
|
|
|
+ {
|
|
|
+ //var context = new ValidationContext<object>(e.FieldIdentifier.Model, new PropertyChain(), new MemberNameValidatorSelector([e.FieldIdentifier.FieldName]));
|
|
|
+ var context = new ValidationContext<object>(CurrentEditContext!.Model, new PropertyChain(), new MemberNameValidatorSelector([e.FieldIdentifier.FieldName]));
|
|
|
+ var validationResults = await Validator!.ValidateAsync(context);
|
|
|
+
|
|
|
+ _messages!.Clear(e.FieldIdentifier);
|
|
|
+ foreach (var validationResult in validationResults.Errors)
|
|
|
+ {
|
|
|
+ _messages.Add(e.FieldIdentifier, validationResult.ErrorMessage);
|
|
|
+ }
|
|
|
+
|
|
|
+ CurrentEditContext!.NotifyValidationStateChanged();
|
|
|
+ }
|
|
|
+
|
|
|
+ private async void CurrentEditContext_OnValidationRequested(object? sender, ValidationRequestedEventArgs e)
|
|
|
+ {
|
|
|
+ var context = new ValidationContext<object>(CurrentEditContext!.Model);
|
|
|
+ var validationResults = await Validator!.ValidateAsync(context);
|
|
|
+
|
|
|
+ _messages!.Clear();
|
|
|
+ foreach (var validationResult in validationResults.Errors)
|
|
|
+ {
|
|
|
+ var fieldIdentifier = CurrentEditContext.Field(validationResult.PropertyName);
|
|
|
+ _messages.Add(fieldIdentifier, validationResult.ErrorMessage);
|
|
|
+ }
|
|
|
+
|
|
|
+ CurrentEditContext.NotifyValidationStateChanged();
|
|
|
+ }
|
|
|
+}
|