diff --git a/src/Umbraco.Abstractions/Models/IPropertyType.cs b/src/Umbraco.Abstractions/Models/IPropertyType.cs
index 7c455d3ba5..6ed5dbd1cb 100644
--- a/src/Umbraco.Abstractions/Models/IPropertyType.cs
+++ b/src/Umbraco.Abstractions/Models/IPropertyType.cs
@@ -75,14 +75,5 @@ namespace Umbraco.Core.Models
/// A value indicating whether wildcards are valid.
bool SupportsVariation(string culture, string segment, bool wildcards = false);
- ///
- /// Converts a value assigned to a property.
- ///
- ///
- /// The input value can be pretty much anything, and is converted to the actual CLR type
- /// expected by the property (eg an integer if the property values are integers).
- /// Throws if the value cannot be converted.
- ///
- object ConvertAssignedValue(object value);
}
}
diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs
index 50a4b9416a..36efbad404 100644
--- a/src/Umbraco.Core/Models/Property.cs
+++ b/src/Umbraco.Core/Models/Property.cs
@@ -295,7 +295,7 @@ namespace Umbraco.Core.Models
if (!PropertyType.SupportsPublishing)
throw new NotSupportedException("Property type does not support publishing.");
var origValue = pvalue.PublishedValue;
- pvalue.PublishedValue = PropertyType.ConvertAssignedValue(pvalue.EditedValue);
+ pvalue.PublishedValue = ConvertAssignedValue(pvalue.EditedValue);
DetectChanges(pvalue.EditedValue, origValue, nameof(Values), PropertyValueComparer, false);
}
@@ -306,7 +306,7 @@ namespace Umbraco.Core.Models
if (!PropertyType.SupportsPublishing)
throw new NotSupportedException("Property type does not support publishing.");
var origValue = pvalue.PublishedValue;
- pvalue.PublishedValue = PropertyType.ConvertAssignedValue(null);
+ pvalue.PublishedValue = ConvertAssignedValue(null);
DetectChanges(pvalue.EditedValue, origValue, nameof(Values), PropertyValueComparer, false);
}
@@ -324,7 +324,7 @@ namespace Umbraco.Core.Models
var (pvalue, change) = GetPValue(culture, segment, true);
var origValue = pvalue.EditedValue;
- var setValue = PropertyType.ConvertAssignedValue(value);
+ var setValue = ConvertAssignedValue(value);
pvalue.EditedValue = setValue;
@@ -380,6 +380,128 @@ namespace Umbraco.Core.Models
return (pvalue, change);
}
+ ///
+ public object ConvertAssignedValue(object value) => TryConvertAssignedValue(value, true, out var converted) ? converted : null;
+
+ ///
+ /// Tries to convert a value assigned to a property.
+ ///
+ ///
+ ///
+ ///
+ private bool TryConvertAssignedValue(object value, bool throwOnError, out object converted)
+ {
+ var isOfExpectedType = IsOfExpectedPropertyType(value);
+ if (isOfExpectedType)
+ {
+ converted = value;
+ return true;
+ }
+
+ // isOfExpectedType is true if value is null - so if false, value is *not* null
+ // "garbage-in", accept what we can & convert
+ // throw only if conversion is not possible
+
+ var s = value.ToString();
+ converted = null;
+
+ switch (ValueStorageType)
+ {
+ case ValueStorageType.Nvarchar:
+ case ValueStorageType.Ntext:
+ {
+ converted = s;
+ return true;
+ }
+
+ case ValueStorageType.Integer:
+ if (s.IsNullOrWhiteSpace())
+ return true; // assume empty means null
+ var convInt = value.TryConvertTo();
+ if (convInt)
+ {
+ converted = convInt.Result;
+ return true;
+ }
+
+ if (throwOnError)
+ ThrowTypeException(value, typeof(int), Alias);
+ return false;
+
+ case ValueStorageType.Decimal:
+ if (s.IsNullOrWhiteSpace())
+ return true; // assume empty means null
+ var convDecimal = value.TryConvertTo();
+ if (convDecimal)
+ {
+ // need to normalize the value (change the scaling factor and remove trailing zeros)
+ // because the underlying database is going to mess with the scaling factor anyways.
+ converted = convDecimal.Result.Normalize();
+ return true;
+ }
+
+ if (throwOnError)
+ ThrowTypeException(value, typeof(decimal), Alias);
+ return false;
+
+ case ValueStorageType.Date:
+ if (s.IsNullOrWhiteSpace())
+ return true; // assume empty means null
+ var convDateTime = value.TryConvertTo();
+ if (convDateTime)
+ {
+ converted = convDateTime.Result;
+ return true;
+ }
+
+ if (throwOnError)
+ ThrowTypeException(value, typeof(DateTime), Alias);
+ return false;
+
+ default:
+ throw new NotSupportedException($"Not supported storage type \"{ValueStorageType}\".");
+ }
+ }
+
+ private static void ThrowTypeException(object value, Type expected, string alias)
+ {
+ throw new InvalidOperationException($"Cannot assign value \"{value}\" of type \"{value.GetType()}\" to property \"{alias}\" expecting type \"{expected}\".");
+ }
+
+ ///
+ /// Determines whether a value is of the expected type for this property type.
+ ///
+ ///
+ /// If the value is of the expected type, it can be directly assigned to the property.
+ /// Otherwise, some conversion is required.
+ ///
+ private bool IsOfExpectedPropertyType(object value)
+ {
+ // null values are assumed to be ok
+ if (value == null)
+ return true;
+
+ // check if the type of the value matches the type from the DataType/PropertyEditor
+ // then it can be directly assigned, anything else requires conversion
+ var valueType = value.GetType();
+ switch (ValueStorageType)
+ {
+ case ValueStorageType.Integer:
+ return valueType == typeof(int);
+ case ValueStorageType.Decimal:
+ return valueType == typeof(decimal);
+ case ValueStorageType.Date:
+ return valueType == typeof(DateTime);
+ case ValueStorageType.Nvarchar:
+ return valueType == typeof(string);
+ case ValueStorageType.Ntext:
+ return valueType == typeof(string);
+ default:
+ throw new NotSupportedException($"Not supported storage type \"{ValueStorageType}\".");
+ }
+ }
+
+
protected override void PerformDeepClone(object clone)
{
base.PerformDeepClone(clone);
diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs
index 2848caf791..65c0ffeade 100644
--- a/src/Umbraco.Core/Models/PropertyType.cs
+++ b/src/Umbraco.Core/Models/PropertyType.cs
@@ -210,128 +210,6 @@ namespace Umbraco.Core.Models
return Variations.ValidateVariation(culture, segment, true, wildcards, false);
}
- ///
- /// Determines whether a value is of the expected type for this property type.
- ///
- ///
- /// If the value is of the expected type, it can be directly assigned to the property.
- /// Otherwise, some conversion is required.
- ///
- private bool IsOfExpectedPropertyType(object value)
- {
- // null values are assumed to be ok
- if (value == null)
- return true;
-
- // check if the type of the value matches the type from the DataType/PropertyEditor
- // then it can be directly assigned, anything else requires conversion
- var valueType = value.GetType();
- switch (ValueStorageType)
- {
- case ValueStorageType.Integer:
- return valueType == typeof(int);
- case ValueStorageType.Decimal:
- return valueType == typeof(decimal);
- case ValueStorageType.Date:
- return valueType == typeof(DateTime);
- case ValueStorageType.Nvarchar:
- return valueType == typeof(string);
- case ValueStorageType.Ntext:
- return valueType == typeof(string);
- default:
- throw new NotSupportedException($"Not supported storage type \"{ValueStorageType}\".");
- }
- }
-
- ///
- public object ConvertAssignedValue(object value) => TryConvertAssignedValue(value, true, out var converted) ? converted : null;
-
- ///
- /// Tries to convert a value assigned to a property.
- ///
- ///
- ///
- ///
- private bool TryConvertAssignedValue(object value, bool throwOnError, out object converted)
- {
- var isOfExpectedType = IsOfExpectedPropertyType(value);
- if (isOfExpectedType)
- {
- converted = value;
- return true;
- }
-
- // isOfExpectedType is true if value is null - so if false, value is *not* null
- // "garbage-in", accept what we can & convert
- // throw only if conversion is not possible
-
- var s = value.ToString();
- converted = null;
-
- switch (ValueStorageType)
- {
- case ValueStorageType.Nvarchar:
- case ValueStorageType.Ntext:
- {
- converted = s;
- return true;
- }
-
- case ValueStorageType.Integer:
- if (s.IsNullOrWhiteSpace())
- return true; // assume empty means null
- var convInt = value.TryConvertTo();
- if (convInt)
- {
- converted = convInt.Result;
- return true;
- }
-
- if (throwOnError)
- ThrowTypeException(value, typeof(int), Alias);
- return false;
-
- case ValueStorageType.Decimal:
- if (s.IsNullOrWhiteSpace())
- return true; // assume empty means null
- var convDecimal = value.TryConvertTo();
- if (convDecimal)
- {
- // need to normalize the value (change the scaling factor and remove trailing zeros)
- // because the underlying database is going to mess with the scaling factor anyways.
- converted = convDecimal.Result.Normalize();
- return true;
- }
-
- if (throwOnError)
- ThrowTypeException(value, typeof(decimal), Alias);
- return false;
-
- case ValueStorageType.Date:
- if (s.IsNullOrWhiteSpace())
- return true; // assume empty means null
- var convDateTime = value.TryConvertTo();
- if (convDateTime)
- {
- converted = convDateTime.Result;
- return true;
- }
-
- if (throwOnError)
- ThrowTypeException(value, typeof(DateTime), Alias);
- return false;
-
- default:
- throw new NotSupportedException($"Not supported storage type \"{ValueStorageType}\".");
- }
- }
-
- private static void ThrowTypeException(object value, Type expected, string alias)
- {
- throw new InvalidOperationException($"Cannot assign value \"{value}\" of type \"{value.GetType()}\" to property \"{alias}\" expecting type \"{expected}\".");
- }
-
-
///
/// Sanitizes a property type alias.
///