From ef26fc1b9c34e2e4afe8d16d61dbfc11e431b204 Mon Sep 17 00:00:00 2001 From: Chris Sainty Date: Sat, 22 Jul 2023 09:44:18 +0100 Subject: [PATCH 1/4] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b129d69..dea1bf4 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ # FluentValidation A library for using FluentValidation with Blazor +[![Nuget version](https://img.shields.io/nuget/v/Blazored.FluentValidation.svg?logo=nuget)](https://www.nuget.org/packages/Blazored.FluentValidation/) +[![Nuget downloads](https://img.shields.io/nuget/dt/Blazored.FluentValidation?logo=nuget)](https://www.nuget.org/packages/Blazored.FluentValidation/) ![Build & Test Main](https://github.com/Blazored/FluentValidation/workflows/Build%20&%20Test%20Main/badge.svg) -![Nuget](https://img.shields.io/nuget/v/blazored.fluentvalidation.svg) - ## Installing You can install from Nuget using the following command: From a6291d29f5436d55343447447777845592b2b65f Mon Sep 17 00:00:00 2001 From: luetm Date: Sun, 18 Feb 2024 16:21:45 +0100 Subject: [PATCH 2/4] Make full validation result details available (also per field) (#212) * Added support for accessing the full validation result on a per field basis. * Undid the rider autoformats. --- README.md | 28 +++++++++++++++++++ .../EditContextFluentValidationExtensions.cs | 12 ++++++++ .../FluentValidationsValidator.cs | 20 +++++++++++++ 3 files changed, 60 insertions(+) diff --git a/README.md b/README.md index dea1bf4..0a47bfb 100644 --- a/README.md +++ b/README.md @@ -130,3 +130,31 @@ The second is when manually validating the model using the `Validate` or `Valida => _fluentValidationValidator?.Validate(options => options.IncludeRuleSets("Names")); } ``` + +## Access to full `ValidationFailure` +If you need details about the specifics of a validation result (e.g. its `Severity), you can access the result of the +last validation by calling the `GetFailuresFromLastValidation` method on the `FluentValidationValidator` component. + +```razor +
+ +
+ +@code { + private FluentValidationValidator? _fluentValidationValidator; + + private string GetValidationClass() + { + var lastResult = _fluentValidationValidator?.GetFailuresFromLastValidation(); + if (lastResult is null || !lastResult.Any()) + { + return "valid"; + } + if (lastResult.Any(failure => failure.Severity == Severity.Error)) + { + return "invalid"; + } + return "warning"; + } +} +``` \ No newline at end of file diff --git a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs index c06c9f4..24fba59 100644 --- a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs +++ b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs @@ -1,5 +1,6 @@ using FluentValidation; using FluentValidation.Internal; +using FluentValidation.Results; using Microsoft.AspNetCore.Components.Forms; using Microsoft.Extensions.DependencyInjection; using static FluentValidation.AssemblyScanner; @@ -57,10 +58,21 @@ private static async Task ValidateModel(EditContext editContext, var validationResults = await asyncValidationTask; messages.Clear(); + fluentValidationValidator.LastValidationResult = new Dictionary>(); + foreach (var validationResult in validationResults.Errors) { var fieldIdentifier = ToFieldIdentifier(editContext, validationResult.PropertyName); messages.Add(fieldIdentifier, validationResult.ErrorMessage); + + if (fluentValidationValidator.LastValidationResult.TryGetValue(fieldIdentifier, out var failures)) + { + failures.Add(validationResult); + } + else + { + fluentValidationValidator.LastValidationResult.Add(fieldIdentifier, new List { validationResult }); + } } editContext.NotifyValidationStateChanged(); diff --git a/src/Blazored.FluentValidation/FluentValidationsValidator.cs b/src/Blazored.FluentValidation/FluentValidationsValidator.cs index ae8e6f9..0f8ee8a 100644 --- a/src/Blazored.FluentValidation/FluentValidationsValidator.cs +++ b/src/Blazored.FluentValidation/FluentValidationsValidator.cs @@ -17,6 +17,7 @@ public class FluentValidationValidator : ComponentBase [Parameter] public bool DisableAssemblyScanning { get; set; } [Parameter] public Action>? Options { get; set; } internal Action>? ValidateOptions { get; set; } + internal Dictionary>? LastValidationResult { get; set; } public bool Validate(Action>? options = null) { @@ -81,4 +82,23 @@ protected override void OnInitialized() CurrentEditContext.AddFluentValidation(ServiceProvider, DisableAssemblyScanning, Validator, this); } + + /// + /// Gets the full details of the last validation result, optionally by field. + /// + /// If set, only returns the validation failures pertaining to the given field. + /// Validation failures. + public ValidationFailure[] GetFailuresFromLastValidation(FieldIdentifier? fieldIdentifier = null) + { + if (LastValidationResult is null) + return Array.Empty(); + + if (fieldIdentifier is null) + return LastValidationResult.Values.SelectMany(f => f).ToArray(); + + if (!LastValidationResult.TryGetValue(fieldIdentifier.Value, out var failures)) + return Array.Empty(); + + return failures.ToArray(); + } } \ No newline at end of file From aaa5514d1568af3a0980087723b286cf997f5445 Mon Sep 17 00:00:00 2001 From: p6laris <71460146+p6laris@users.noreply.github.com> Date: Sun, 18 Feb 2024 18:23:45 +0300 Subject: [PATCH 3/4] Update README.md (#208) Co-authored-by: Chris Sainty --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0a47bfb..02b1e46 100644 --- a/README.md +++ b/README.md @@ -97,9 +97,9 @@ If you're using async validation, you can use the `ValidateAsync` method on the @code { private Person _person = new(); - private FluentValidationValidator? _fluentValidationValidator; + private FluentValidationValidator? _fluentValidationValidator; - private void SubmitFormAsync() + private async void SubmitFormAsync() { if (await _fluentValidationValidator!.ValidateAsync()) { From 26c7bb62477de7059f0687ff75c0d172d8e7c4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Raffael=20Sch=C3=A4rer?= Date: Tue, 20 Feb 2024 16:28:25 +0100 Subject: [PATCH 4/4] Addresses an issue with collection expressions in C# 12 regarding IReadOnlyList --- .../EditContextFluentValidationExtensions.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs index 24fba59..7ab8ab8 100644 --- a/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs +++ b/src/Blazored.FluentValidation/EditContextFluentValidationExtensions.cs @@ -199,6 +199,16 @@ private static FieldIdentifier ToFieldIdentifier(in EditContext editContext, in var indexerValue = int.Parse(nextToken); newObj = array[indexerValue]; } + else if (obj is IReadOnlyList readOnlyList) + { + // Addresses an issue with collection expressions in C# 12 regarding IReadOnlyList: + // Generates a <>z__ReadOnlyArray which: + // - lacks an Item property, and + // - cannot be cast to object[] successfully. + // This workaround accesses elements directly using an indexer. + var indexerValue = int.Parse(nextToken); + newObj = readOnlyList[indexerValue]; + } else { throw new InvalidOperationException($"Could not find indexer on object of type {obj.GetType().FullName}.");