From eb97f54188959d55bf8efd2ed1fa25c1a2235ea3 Mon Sep 17 00:00:00 2001 From: Jeremy Skinner <90130+JeremySkinner@users.noreply.github.com> Date: Thu, 26 May 2022 12:09:18 +0100 Subject: [PATCH] Support deserialization with System.Text.Json --- .../JsonSerializationTests.cs | 35 +++++++++++++++++++ .../Results/ValidationFailure.cs | 3 +- .../Results/ValidationResult.cs | 11 ++++-- 3 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 src/FluentValidation.Tests/JsonSerializationTests.cs diff --git a/src/FluentValidation.Tests/JsonSerializationTests.cs b/src/FluentValidation.Tests/JsonSerializationTests.cs new file mode 100644 index 000000000..717c5950e --- /dev/null +++ b/src/FluentValidation.Tests/JsonSerializationTests.cs @@ -0,0 +1,35 @@ +namespace FluentValidation.Tests; + +using System.Text.Json; +using Results; +using Xunit; + +public class JsonSerializationTests { + + [Fact] + public void SystemTextJson_deserialization_should_be_consistent_with_newtonsoft() { + var validationResult = new ValidationResult { + Errors = { + new ValidationFailure("MyProperty1", "Invalid MyProperty1"), + new ValidationFailure("MyProperty2", "Invalid MyProperty2"), + new ValidationFailure("MyProperty3", "Invalid MyProperty3") + } + }; + // System.Text.Json + var serialized1 = JsonSerializer.Serialize(validationResult); + var deserialized1 = JsonSerializer.Deserialize(serialized1); + + // Newtonsoft.Json + var serialized2 = Newtonsoft.Json.JsonConvert.SerializeObject(validationResult); + var deserialized2 = Newtonsoft.Json.JsonConvert.DeserializeObject(serialized2); + + Assert.NotNull(deserialized1); + Assert.Equal(deserialized1.IsValid, deserialized2.IsValid); + Assert.Equal(deserialized1.Errors.Count, deserialized2.Errors.Count); + + for (var i = 0; i < deserialized1.Errors.Count; i++) { + Assert.Equal(deserialized1.Errors[i].PropertyName, deserialized2.Errors[i].PropertyName); + Assert.Equal(deserialized1.Errors[i].ErrorMessage, deserialized2.Errors[i].ErrorMessage); + } + } +} diff --git a/src/FluentValidation/Results/ValidationFailure.cs b/src/FluentValidation/Results/ValidationFailure.cs index c45efc40c..9114244e5 100644 --- a/src/FluentValidation/Results/ValidationFailure.cs +++ b/src/FluentValidation/Results/ValidationFailure.cs @@ -25,7 +25,8 @@ namespace FluentValidation.Results { /// [Serializable] public class ValidationFailure { - private ValidationFailure() { + + public ValidationFailure() { } diff --git a/src/FluentValidation/Results/ValidationResult.cs b/src/FluentValidation/Results/ValidationResult.cs index 526e907e9..9e59932c2 100644 --- a/src/FluentValidation/Results/ValidationResult.cs +++ b/src/FluentValidation/Results/ValidationResult.cs @@ -26,7 +26,7 @@ namespace FluentValidation.Results { /// [Serializable] public class ValidationResult { - private readonly List _errors; + private List _errors; /// /// Whether validation succeeded @@ -36,7 +36,14 @@ public class ValidationResult { /// /// A collection of errors /// - public List Errors => _errors; + public List Errors { + get => _errors; +#if NETSTANDARD2_0_OR_GREATER + set => _errors = value ?? throw new ArgumentNullException(nameof(value)); +#else + init => _errors = value ?? throw new ArgumentNullException(nameof(value)); +#endif + } public string[] RuleSetsExecuted { get; internal set; }