Cleans up IPropertyType since we don't need the method ConvertAssignedValue as an abstraction
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object ConvertAssignedValue(object value) => TryConvertAssignedValue(value, true, out var converted) ? converted : null;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to convert a value assigned to a property.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para></para>
|
||||
/// </remarks>
|
||||
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<int>();
|
||||
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<decimal>();
|
||||
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<DateTime>();
|
||||
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}\".");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a value is of the expected type for this property type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>If the value is of the expected type, it can be directly assigned to the property.
|
||||
/// Otherwise, some conversion is required.</para>
|
||||
/// </remarks>
|
||||
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);
|
||||
|
||||
@@ -210,128 +210,6 @@ namespace Umbraco.Core.Models
|
||||
return Variations.ValidateVariation(culture, segment, true, wildcards, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a value is of the expected type for this property type.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>If the value is of the expected type, it can be directly assigned to the property.
|
||||
/// Otherwise, some conversion is required.</para>
|
||||
/// </remarks>
|
||||
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}\".");
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object ConvertAssignedValue(object value) => TryConvertAssignedValue(value, true, out var converted) ? converted : null;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to convert a value assigned to a property.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para></para>
|
||||
/// </remarks>
|
||||
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<int>();
|
||||
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<decimal>();
|
||||
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<DateTime>();
|
||||
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}\".");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sanitizes a property type alias.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user