diff --git a/src/Umbraco.Web/Models/PublishedProperty.cs b/src/Umbraco.Web/Models/PublishedProperty.cs
index b24d1260a3..0865f8f915 100644
--- a/src/Umbraco.Web/Models/PublishedProperty.cs
+++ b/src/Umbraco.Web/Models/PublishedProperty.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -25,58 +26,56 @@ namespace Umbraco.Web.Models
/// Ensures that all conversions took place correctly.
internal static IEnumerable MapProperties(
IEnumerable propertyTypes, IEnumerable properties,
- Func map)
+ Func map)
{
- var peResolver = DataTypesResolver.Current;
- var dtService = ApplicationContext.Current.Services.DataTypeService;
- return MapProperties(propertyTypes, properties, peResolver, dtService, map);
+ return propertyTypes.Select(x =>
+ {
+ var property = properties.SingleOrDefault(xx => xx.Alias == x.PropertyTypeAlias);
+ var value = property == null ? null : property.Value;
+ return map(x, ConvertPropertyValueFromDbToData(x, value));
+ });
}
///
- /// Maps a collection of Property to a collection of IPublishedProperty for a specified collection of PublishedPropertyType.
+ /// Converts a database property value to a "data" value ie a value that we can pass to
+ /// IPropertyValueConverter.
///
- /// The published property types.
- /// The properties.
- /// A mapping function.
- /// A DataTypesResolver instance.
- /// An IDataTypeService instance.
- /// A collection of IPublishedProperty corresponding to the collection of PublishedPropertyType
- /// and taking values from the collection of Property.
- /// Ensures that all conversions took place correctly.
- internal static IEnumerable MapProperties(
- IEnumerable propertyTypes, IEnumerable properties,
- DataTypesResolver dataTypesResolver, IDataTypeService dataTypeService,
- Func map)
+ /// The published property type.
+ /// The value.
+ /// The converted value.
+ internal static object ConvertPropertyValueFromDbToData(PublishedPropertyType propertyType, object value)
{
- return propertyTypes
- .Select(x =>
- {
- var p = properties.SingleOrDefault(xx => xx.Alias == x.PropertyTypeAlias);
- var v = p == null || p.Value == null ? null : p.Value;
- if (v != null)
- {
- // note - not sure about the performance here
- var dataTypeDefinition = global::umbraco.cms.businesslogic.datatype.DataTypeDefinition
- .GetDataTypeDefinition(x.DataTypeId);
- var dataType = dataTypeDefinition.DataType;
- if (dataType != null)
- {
- var data = dataType.Data;
- data.Value = v;
- var n = data.ToXMl(new XmlDocument());
- if (n.NodeType == XmlNodeType.CDATA || n.NodeType == XmlNodeType.Text)
- v = n.InnerText;
- else if (n.NodeType == XmlNodeType.Element)
- v = n.InnerXml;
- // note - is there anything else we should take care of?
- }
- }
- // fixme - means that the IPropertyValueConverter will always get a string
- // fixme and never an int or DateTime that's in the DB unless the value editor has
- // fixme a way to say it's OK to use what's in the DB?
+ if (value == null) return null;
- return map(x, p, v);
- });
+ // We are converting to string, even for database values which are integer or
+ // DateTime, which is not optimum. Doing differently would require that we have a way to tell
+ // whether the conversion to XML string changes something or not... which we don't, and we
+ // don't want to implement it as PropertyValueEditor.ConvertDbToXml/String should die anyway.
+
+ // Don't think about improving the situation here: this is a corner case and the real
+ // thing to do is to get rig of PropertyValueEditor.ConvertDbToXml/String.
+
+ // works but better use the new API
+ //var dataTypeDefinition = global::umbraco.cms.businesslogic.datatype.DataTypeDefinition.GetDataTypeDefinition(propertyType.DataTypeId);
+ //var dataType = dataTypeDefinition.DataType;
+
+ // transient resolver will create a new object each time we call it
+ // so it is safe to alter DataTypeDefinitionId, Data, etc.
+ var dataType = DataTypesResolver.Current.GetById(propertyType.PropertyEditorGuid);
+ if (dataType != null)
+ {
+ dataType.DataTypeDefinitionId = propertyType.DataTypeId; // required else conversion fails
+ var data = dataType.Data;
+ data.Value = value;
+ var n = data.ToXMl(new XmlDocument());
+ if (n.NodeType == XmlNodeType.CDATA || n.NodeType == XmlNodeType.Text)
+ value = n.InnerText;
+ else if (n.NodeType == XmlNodeType.Element)
+ value = n.InnerXml;
+ // assuming there are no other node types that we need to take care of
+ }
+
+ return value;
}
}
}
diff --git a/src/Umbraco.Web/PublishedCache/MemberPublishedContent.cs b/src/Umbraco.Web/PublishedCache/MemberPublishedContent.cs
index e538d135d3..bdbc28f3cf 100644
--- a/src/Umbraco.Web/PublishedCache/MemberPublishedContent.cs
+++ b/src/Umbraco.Web/PublishedCache/MemberPublishedContent.cs
@@ -34,7 +34,7 @@ namespace Umbraco.Web.PublishedCache
throw new InvalidOperationException("Could not get member type with alias " + _member.ContentTypeAlias);
}
_properties = PublishedProperty.MapProperties(_publishedMemberType.PropertyTypes, _member.Properties,
- (t, p, v) => new RawValueProperty(t, v ?? string.Empty))
+ (t, v) => new RawValueProperty(t, v ?? string.Empty))
.ToArray();
}