diff --git a/src/Umbraco.Tests/Web/Validation/ContentModelValidatorTests.cs b/src/Umbraco.Tests/Web/Validation/ContentModelValidatorTests.cs index 29a8f9ebb7..8c52c7e918 100644 --- a/src/Umbraco.Tests/Web/Validation/ContentModelValidatorTests.cs +++ b/src/Umbraco.Tests/Web/Validation/ContentModelValidatorTests.cs @@ -97,17 +97,17 @@ namespace Umbraco.Tests.Web.Validation [Test] public void TestSerializer() { - var nestedLevel2 = new NestedValidationResults(); - var elementTypeResult2 = new ElementTypeValidationResult("type2"); - var propertyTypeResult2 = new PropertyTypeValidationResult("prop2"); + var nestedLevel2 = new ComplexEditorValidationResult(); + var elementTypeResult2 = new ComplexEditorElementTypeValidationResult("type2"); + var propertyTypeResult2 = new ComplexEditorPropertyTypeValidationResult("prop2"); propertyTypeResult2.ValidationResults.Add(new ValidationResult("error2-1", new[] { "level2" })); propertyTypeResult2.ValidationResults.Add(new ValidationResult("error2-2", new[] { "level2" })); elementTypeResult2.ValidationResults.Add(propertyTypeResult2); nestedLevel2.ValidationResults.Add(elementTypeResult2); - var nestedLevel1 = new NestedValidationResults(); - var elementTypeResult1 = new ElementTypeValidationResult("type1"); - var propertyTypeResult1 = new PropertyTypeValidationResult("prop1"); + var nestedLevel1 = new ComplexEditorValidationResult(); + var elementTypeResult1 = new ComplexEditorElementTypeValidationResult("type1"); + var propertyTypeResult1 = new ComplexEditorPropertyTypeValidationResult("prop1"); propertyTypeResult1.ValidationResults.Add(new ValidationResult("error1-1", new[] { "level1" })); propertyTypeResult1.ValidationResults.Add(nestedLevel2); // This is a nested result within the level 1 elementTypeResult1.ValidationResults.Add(propertyTypeResult1); @@ -115,6 +115,11 @@ namespace Umbraco.Tests.Web.Validation var serialized = JsonConvert.SerializeObject(nestedLevel1, Formatting.Indented, new ValidationResultConverter()); Console.WriteLine(serialized); + + var jsonNestedError = JsonConvert.DeserializeObject(serialized); + Assert.AreEqual(JTokenType.Array, jsonNestedError["nestedValidation"].Type); + var nestedValidation = (JArray)jsonNestedError["nestedValidation"]; + AssertNestedValidation(nestedValidation); } [Test] @@ -226,12 +231,12 @@ namespace Umbraco.Tests.Web.Validation var jsonNestedError = JsonConvert.DeserializeObject(nestedError.ErrorMessage); Assert.AreEqual(JTokenType.Array, jsonNestedError["nestedValidation"].Type); var nestedValidation = (JArray)jsonNestedError["nestedValidation"]; - AssertNestedValidation(nestedValidation, 2); // there are 2 because there are 2 nested content rows + AssertNestedValidation(nestedValidation); } - private void AssertNestedValidation(JArray nestedValidation, int rows) + private void AssertNestedValidation(JArray nestedValidation) { - Assert.AreEqual(rows, nestedValidation.Count); + Assert.Greater(nestedValidation.Count, 0); foreach (var rowErrors in nestedValidation) { Assert.AreEqual(JTokenType.Object, rowErrors.Type); @@ -239,7 +244,7 @@ namespace Umbraco.Tests.Web.Validation Assert.AreEqual(1, elementTypeErrors.Count); // there is 1 element type in error foreach (var elementTypeAliasToErrors in elementTypeErrors) { - Assert.AreEqual("textPage", elementTypeAliasToErrors.Key); + Assert.IsNotEmpty(elementTypeAliasToErrors.Key); var propErrors = (JObject)elementTypeAliasToErrors.Value; foreach (var propAliasToErrors in propErrors) @@ -253,19 +258,15 @@ namespace Umbraco.Tests.Web.Validation if (nested != null) { // recurse - AssertNestedValidation((JArray)nested, 1); // we know this is 1 row + AssertNestedValidation((JArray)nested); continue; } Assert.IsNotEmpty(propError["errorMessage"].Value()); Assert.AreEqual(1, propError["memberNames"].Value().Count); } - } - } - - } } diff --git a/src/Umbraco.Web/ModelStateExtensions.cs b/src/Umbraco.Web/ModelStateExtensions.cs index 718094e6b5..8002c32e61 100644 --- a/src/Umbraco.Web/ModelStateExtensions.cs +++ b/src/Umbraco.Web/ModelStateExtensions.cs @@ -54,7 +54,7 @@ namespace Umbraco.Web ValidationResult result, string propertyAlias, string culture = "", string segment = "") { - var propValidationResult = new PropertyValidationResult(result); + var propValidationResult = new ContentPropertyValidationResult(result); var keyParts = new[] { diff --git a/src/Umbraco.Web/PropertyEditors/ComplexEditorValidator.cs b/src/Umbraco.Web/PropertyEditors/ComplexEditorValidator.cs index 16a3357cbb..b65c872e68 100644 --- a/src/Umbraco.Web/PropertyEditors/ComplexEditorValidator.cs +++ b/src/Umbraco.Web/PropertyEditors/ComplexEditorValidator.cs @@ -23,7 +23,7 @@ namespace Umbraco.Web.PropertyEditors } /// - /// Return a single for all sub nested validation results in the complex editor + /// Return a single for all sub nested validation results in the complex editor /// /// /// @@ -36,7 +36,7 @@ namespace Umbraco.Web.PropertyEditors if (rowResults.Count > 0) { - var result = new NestedValidationResults(); + var result = new ComplexEditorValidationResult(); foreach(var rowResult in rowResults) { result.ValidationResults.Add(rowResult); @@ -55,15 +55,15 @@ namespace Umbraco.Web.PropertyEditors /// /// /// - protected IEnumerable GetNestedValidationResults(IEnumerable elements) + protected IEnumerable GetNestedValidationResults(IEnumerable elements) { foreach (var row in elements) { - var elementTypeValidationResult = new ElementTypeValidationResult(row.ElementTypeAlias); + var elementTypeValidationResult = new ComplexEditorElementTypeValidationResult(row.ElementTypeAlias); foreach (var prop in row.PropertyTypeValidation) { - var propValidationResult = new PropertyTypeValidationResult(prop.PropertyType.Alias); + var propValidationResult = new ComplexEditorPropertyTypeValidationResult(prop.PropertyType.Alias); foreach (var validationResult in _propertyValidationService.ValidatePropertyValue(prop.PropertyType, prop.PostedValue)) { diff --git a/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorElementTypeValidationResult.cs b/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorElementTypeValidationResult.cs new file mode 100644 index 0000000000..d43c3ed13d --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorElementTypeValidationResult.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Umbraco.Web.PropertyEditors.Validation +{ + /// + /// A collection of for an element type within complex editor represented by an Element Type + /// + public class ComplexEditorElementTypeValidationResult : ValidationResult + { + public ComplexEditorElementTypeValidationResult(string elementTypeAlias) + : base(string.Empty) + { + ElementTypeAlias = elementTypeAlias; + } + + public IList ValidationResults { get; } = new List(); + public string ElementTypeAlias { get; } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorPropertyTypeValidationResult.cs b/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorPropertyTypeValidationResult.cs new file mode 100644 index 0000000000..20ba3a27d3 --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorPropertyTypeValidationResult.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Umbraco.Web.PropertyEditors.Validation +{ + /// + /// A collection of for a property type within a complex editor represented by an Element Type + /// + public class ComplexEditorPropertyTypeValidationResult : ValidationResult + { + public ComplexEditorPropertyTypeValidationResult(string propertyTypeAlias) + : base(string.Empty) + { + PropertyTypeAlias = propertyTypeAlias; + } + + public IList ValidationResults { get; } = new List(); + public string PropertyTypeAlias { get; } + } +} diff --git a/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorValidationResult.cs b/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorValidationResult.cs new file mode 100644 index 0000000000..eb1efbc64f --- /dev/null +++ b/src/Umbraco.Web/PropertyEditors/Validation/ComplexEditorValidationResult.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; + +namespace Umbraco.Web.PropertyEditors.Validation +{ + + /// + /// A collection of for a complex editor represented by an Element Type + /// + /// + /// For example, each represents validation results for a row in Nested Content + /// + public class ComplexEditorValidationResult : ValidationResult + { + public ComplexEditorValidationResult() + : base(string.Empty) + { + } + + public IList ValidationResults { get; } = new List(); + } +} diff --git a/src/Umbraco.Web/PropertyEditors/Validation/PropertyValidationResult.cs b/src/Umbraco.Web/PropertyEditors/Validation/ContentPropertyValidationResult.cs similarity index 69% rename from src/Umbraco.Web/PropertyEditors/Validation/PropertyValidationResult.cs rename to src/Umbraco.Web/PropertyEditors/Validation/ContentPropertyValidationResult.cs index f2c92e441e..9c80f6b8e7 100644 --- a/src/Umbraco.Web/PropertyEditors/Validation/PropertyValidationResult.cs +++ b/src/Umbraco.Web/PropertyEditors/Validation/ContentPropertyValidationResult.cs @@ -8,12 +8,12 @@ namespace Umbraco.Web.PropertyEditors.Validation /// /// This clones the original result and then ensures the nested result if it's the correct type /// - public class PropertyValidationResult : ValidationResult + public class ContentPropertyValidationResult : ValidationResult { - public PropertyValidationResult(ValidationResult nested) + public ContentPropertyValidationResult(ValidationResult nested) : base(nested.ErrorMessage, nested.MemberNames) { - NestedResuls = nested as NestedValidationResults; + ComplexEditorResults = nested as ComplexEditorValidationResult; } /// @@ -22,6 +22,6 @@ namespace Umbraco.Web.PropertyEditors.Validation /// /// There can be nested results for complex editors that contain other editors /// - public NestedValidationResults NestedResuls { get; } + public ComplexEditorValidationResult ComplexEditorResults { get; } } } diff --git a/src/Umbraco.Web/PropertyEditors/Validation/NestedValidationResults.cs b/src/Umbraco.Web/PropertyEditors/Validation/NestedValidationResults.cs deleted file mode 100644 index 26a47602db..0000000000 --- a/src/Umbraco.Web/PropertyEditors/Validation/NestedValidationResults.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; - -namespace Umbraco.Web.PropertyEditors.Validation -{ - public class PropertyTypeValidationResult : ValidationResult - { - public PropertyTypeValidationResult(string propertyTypeAlias) - : base(string.Empty) - { - PropertyTypeAlias = propertyTypeAlias; - } - - public IList ValidationResults { get; } = new List(); - public string PropertyTypeAlias { get; } - } - - public class ElementTypeValidationResult : ValidationResult - { - public ElementTypeValidationResult(string elementTypeAlias) - : base(string.Empty) - { - ElementTypeAlias = elementTypeAlias; - } - - public IList ValidationResults { get; } = new List(); - public string ElementTypeAlias { get; } - } - - /// - /// Custom that contains a list of nested validation results - /// - /// - /// For example, each represents validation results for a row in Nested Content - /// - public class NestedValidationResults : ValidationResult - { - public NestedValidationResults() - : base(string.Empty) - { - } - - public IList ValidationResults { get; } = new List(); - } -} diff --git a/src/Umbraco.Web/PropertyEditors/Validation/ValidationResultConverter.cs b/src/Umbraco.Web/PropertyEditors/Validation/ValidationResultConverter.cs index cb5e71b060..6769d0bd08 100644 --- a/src/Umbraco.Web/PropertyEditors/Validation/ValidationResultConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/Validation/ValidationResultConverter.cs @@ -4,15 +4,17 @@ using Newtonsoft.Json.Serialization; using System; using System.ComponentModel.DataAnnotations; using System.Linq; -using System.Text; -using System.Threading.Tasks; using Umbraco.Core; namespace Umbraco.Web.PropertyEditors.Validation { /// - /// Custom json converter for and + /// Custom json converter for and /// + /// + /// This converter is specifically used to convert validation results for content in order to be able to have nested + /// validation results for complex editors. + /// internal class ValidationResultConverter : JsonConverter { public override bool CanConvert(Type objectType) => typeof(ValidationResult).IsAssignableFrom(objectType); @@ -34,7 +36,7 @@ namespace Umbraco.Web.PropertyEditors.Validation var validationResult = (ValidationResult)value; - if (validationResult is NestedValidationResults nestedResult && nestedResult.ValidationResults.Count > 0) + if (validationResult is ComplexEditorValidationResult nestedResult && nestedResult.ValidationResults.Count > 0) { var jo = new JObject(); // recurse to write out an array of ValidationResultCollection @@ -42,7 +44,7 @@ namespace Umbraco.Web.PropertyEditors.Validation jo.Add("nestedValidation", obj); jo.WriteTo(writer); } - else if (validationResult is ElementTypeValidationResult elementTypeValidationResult && elementTypeValidationResult.ValidationResults.Count > 0) + else if (validationResult is ComplexEditorElementTypeValidationResult elementTypeValidationResult && elementTypeValidationResult.ValidationResults.Count > 0) { var joElementType = new JObject(); var joPropertyType = new JObject(); @@ -65,11 +67,11 @@ namespace Umbraco.Web.PropertyEditors.Validation else { - if (validationResult is PropertyValidationResult propertyValidationResult - && propertyValidationResult.NestedResuls?.ValidationResults.Count > 0) + if (validationResult is ContentPropertyValidationResult propertyValidationResult + && propertyValidationResult.ComplexEditorResults?.ValidationResults.Count > 0) { // recurse to write out the NestedValidationResults - var obj = JToken.FromObject(propertyValidationResult.NestedResuls, camelCaseSerializer); + var obj = JToken.FromObject(propertyValidationResult.ComplexEditorResults, camelCaseSerializer); obj.WriteTo(writer); } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index f1791908f9..f9aed27684 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -248,8 +248,10 @@ - - + + + +