diff --git a/src/FluentValidation.Tests/JsonSerializationTests.cs b/src/FluentValidation.Tests/JsonSerializationTests.cs new file mode 100644 index 000000000..d44dba44f --- /dev/null +++ b/src/FluentValidation.Tests/JsonSerializationTests.cs @@ -0,0 +1,33 @@ +namespace FluentValidation.Tests { + using System.Text.Json; + using Results; + using Xunit; + + public class JsonSerializationTests { + [Fact] + public void Consecutive_Serialize_Deserialization() { + 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/FluentValidation.csproj b/src/FluentValidation/FluentValidation.csproj index d76e316bf..f63616e9d 100644 --- a/src/FluentValidation/FluentValidation.csproj +++ b/src/FluentValidation/FluentValidation.csproj @@ -24,5 +24,6 @@ Full release notes can be found at https://github.com/FluentValidation/FluentVal + diff --git a/src/FluentValidation/Results/ValidationFailure.cs b/src/FluentValidation/Results/ValidationFailure.cs index c45efc40c..504d1537b 100644 --- a/src/FluentValidation/Results/ValidationFailure.cs +++ b/src/FluentValidation/Results/ValidationFailure.cs @@ -19,6 +19,7 @@ namespace FluentValidation.Results { using System; using System.Collections.Generic; + using System.Text.Json.Serialization; /// /// Defines a validation failure @@ -38,6 +39,7 @@ public class ValidationFailure { /// /// Creates a new ValidationFailure. /// + [JsonConstructor] public ValidationFailure(string propertyName, string errorMessage, object attemptedValue) { PropertyName = propertyName; ErrorMessage = errorMessage; diff --git a/src/FluentValidation/Results/ValidationResult.cs b/src/FluentValidation/Results/ValidationResult.cs index 526e907e9..176675ccf 100644 --- a/src/FluentValidation/Results/ValidationResult.cs +++ b/src/FluentValidation/Results/ValidationResult.cs @@ -20,6 +20,7 @@ namespace FluentValidation.Results { using System; using System.Collections.Generic; using System.Linq; + using System.Text.Json.Serialization; /// /// The result of running a validator @@ -47,6 +48,15 @@ public class ValidationResult { _errors = new List(); } + /// + /// Helps System.Text.Json to deserialize jsons correctly. This constructor cannot be called for other purposes. + /// + [Obsolete] + [JsonConstructor] + public ValidationResult(List errors , bool isValid) { + _errors = errors; + } + /// /// Creates a new ValidationResult from a collection of failures ///