public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) { try { using (var timer = DisposableTimer.DebugDuration <NestedContentValueConverter>(string.Format("ConvertDataToSource ({0})", propertyType.DataTypeId))) { if (source != null && !source.ToString().IsNullOrWhiteSpace()) { var rawValue = JsonConvert.DeserializeObject <List <object> >(source.ToString()); var processedValue = new List <IPublishedContent>(); var preValue = NestedContentHelper.GetPreValuesDictionaryByDataTypeId(propertyType.DataTypeId); var contentType = NestedContentHelper.GetContentTypeFromPreValue(propertyType.DataTypeId); if (contentType == null) { return(null); } var publishedContentType = PublishedContentType.Get(PublishedItemType.Content, contentType.Alias); if (publishedContentType == null) { return(null); } for (var i = 0; i < rawValue.Count; i++) { var o = rawValue[i]; var propValues = ((JObject)o).ToObject <Dictionary <string, object> >(); var properties = new List <IPublishedProperty>(); foreach (var jProp in propValues) { var propType = publishedContentType.GetPropertyType(jProp.Key); if (propType != null) { properties.Add(new DetachedPublishedProperty(propType, jProp.Value)); } } // Parse out the name manually object nameObj = null; if (propValues.TryGetValue("name", out nameObj)) { // Do nothing, we just want to parse out the name if we can } processedValue.Add(new DetachedPublishedContent(nameObj == null ? null : nameObj.ToString(), publishedContentType, properties.ToArray())); } // Detect min/max items == 1 and just return a single IPublishedContent int minItems, maxItems; if (preValue.ContainsKey("minItems") && int.TryParse(preValue["minItems"], out minItems) && minItems == 1 && preValue.ContainsKey("maxItems") && int.TryParse(preValue["maxItems"], out maxItems) && maxItems == 1) { return(processedValue.FirstOrDefault()); } return(processedValue); } } } catch (Exception e) { LogHelper.Error <NestedContentValueConverter>("Error converting value", e); } return(null); }