diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs
index f43e5c4916..49f679d1f4 100644
--- a/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs
+++ b/src/Umbraco.Core/Models/PublishedContent/PublishedPropertyType.cs
@@ -77,7 +77,7 @@ namespace Umbraco.Core.Models.PublishedContent
///
/// Gets the published content type containing the property type.
- ///
+ ///
public PublishedContentType ContentType { get; internal set; } // internally set by PublishedContentType constructor
///
@@ -193,6 +193,20 @@ namespace Umbraco.Core.Models.PublishedContent
_modelClrType = _converter == null ? typeof (object) : _converter.GetPropertyValueType(this);
}
+ ///
+ /// Determines whether a source value is an actual value, or not a value.
+ ///
+ /// Used by property.HasValue and, for instance, in fallback scenarios.
+ public bool IsValue(object value)
+ {
+ // if we have a converter, use the converter,
+ // otherwise use the old magic null & string comparisons
+
+ return _converter == null
+ ? value != null && (!(value is string) || string.IsNullOrWhiteSpace((string) value) == false)
+ : _converter.IsValue(value);
+ }
+
///
/// Gets the property cache level.
///
diff --git a/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs b/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs
index 6bd36a8f6f..53851f8653 100644
--- a/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs
+++ b/src/Umbraco.Core/PropertyEditors/IPropertyValueConverter.cs
@@ -17,6 +17,11 @@ namespace Umbraco.Core.PropertyEditors
/// A value indicating whether the converter supports a property type.
bool IsConverter(PublishedPropertyType propertyType);
+ ///
+ /// Determines whether a source value is an actual value, or not a value.
+ ///
+ bool IsValue(object value);
+
///
/// Gets the type of values returned by the converter.
///
diff --git a/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs b/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs
index 724d7d0b55..9a82446edd 100644
--- a/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs
+++ b/src/Umbraco.Core/PropertyEditors/PropertyValueConverterBase.cs
@@ -9,33 +9,24 @@ namespace Umbraco.Core.PropertyEditors
public abstract class PropertyValueConverterBase : IPropertyValueConverter
{
public virtual bool IsConverter(PublishedPropertyType propertyType)
- {
- return false;
- }
+ => false;
+
+ public bool IsValue(object value)
+ => value != null && (!(value is string) || string.IsNullOrWhiteSpace((string) value) == false);
public virtual Type GetPropertyValueType(PublishedPropertyType propertyType)
- {
- return typeof (object);
- }
+ => typeof (object);
public virtual PropertyCacheLevel GetPropertyCacheLevel(PublishedPropertyType propertyType)
- {
- return PropertyCacheLevel.Snapshot;
- }
+ => PropertyCacheLevel.Snapshot;
public virtual object ConvertSourceToIntermediate(IPublishedElement owner, PublishedPropertyType propertyType, object source, bool preview)
- {
- return source;
- }
+ => source;
public virtual object ConvertIntermediateToObject(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
- {
- return inter;
- }
+ => inter;
public virtual object ConvertIntermediateToXPath(IPublishedElement owner, PublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
- {
- return inter?.ToString() ?? string.Empty;
- }
+ => inter?.ToString() ?? string.Empty;
}
}
diff --git a/src/Umbraco.Tests/Published/ConvertersTests.cs b/src/Umbraco.Tests/Published/ConvertersTests.cs
index 25933fdd9d..39cb37f160 100644
--- a/src/Umbraco.Tests/Published/ConvertersTests.cs
+++ b/src/Umbraco.Tests/Published/ConvertersTests.cs
@@ -47,6 +47,9 @@ namespace Umbraco.Tests.Published
private class SimpleConverter1 : IPropertyValueConverter
{
+ public bool IsValue(object value)
+ => value != null && (!(value is string) || string.IsNullOrWhiteSpace((string) value) == false);
+
public bool IsConverter(PublishedPropertyType propertyType)
=> propertyType.EditorAlias.InvariantEquals("Umbraco.Void");
@@ -117,6 +120,9 @@ namespace Umbraco.Tests.Published
_cacheLevel = cacheLevel;
}
+ public bool IsValue(object value)
+ => value != null && (!(value is string) || string.IsNullOrWhiteSpace((string) value) == false);
+
public bool IsConverter(PublishedPropertyType propertyType)
=> propertyType.EditorAlias.InvariantEquals("Umbraco.Void");
diff --git a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs
index 950d81ee36..617429d205 100644
--- a/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs
+++ b/src/Umbraco.Tests/Published/PropertyCacheLevelTests.cs
@@ -210,6 +210,9 @@ namespace Umbraco.Tests.Published
public int SourceConverts { get; private set; }
public int InterConverts { get; private set; }
+ public bool IsValue(object value)
+ => value != null && (!(value is string) || string.IsNullOrWhiteSpace((string) value) == false);
+
public bool IsConverter(PublishedPropertyType propertyType)
=> propertyType.EditorAlias.InvariantEquals("Umbraco.Void");
@@ -235,4 +238,4 @@ namespace Umbraco.Tests.Published
=> ((int) inter).ToString();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
index 2d24efdd67..73a159cb19 100644
--- a/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
+++ b/src/Umbraco.Web/PublishedCache/NuCache/Property.cs
@@ -90,11 +90,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
public override bool HasValue(string culture = null, string segment = null)
{
ContextualizeVariation(ref culture, ref segment);
-
- var sourceValue = GetSourceValue(culture, segment);
-
- return sourceValue != null &&
- (!(sourceValue is string) || string.IsNullOrWhiteSpace((string) sourceValue) == false);
+ return PropertyType.IsValue(GetSourceValue(culture, segment));
}
// used to cache the CacheValues of this property