From 11befe727cd61d2d87a1701728ecb8edf5fc8cd4 Mon Sep 17 00:00:00 2001 From: cankoluman Date: Wed, 7 May 2014 13:01:07 +0100 Subject: [PATCH] Issue #AR-3_IEnumerable_support: all tests passing - but branching logic is difficult. --- .../Serialization/ArchetypeJsonConverter.cs | 58 ++++++++++++++----- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/app/Umbraco/Umbraco.Archetype/Serialization/ArchetypeJsonConverter.cs b/app/Umbraco/Umbraco.Archetype/Serialization/ArchetypeJsonConverter.cs index d8e9d6e..e3dfb54 100644 --- a/app/Umbraco/Umbraco.Archetype/Serialization/ArchetypeJsonConverter.cs +++ b/app/Umbraco/Umbraco.Archetype/Serialization/ArchetypeJsonConverter.cs @@ -38,17 +38,31 @@ namespace Archetype.Umbraco.Serialization if (jToken == null) return null; - var obj = Activator.CreateInstance(objectType); - - if (null != obj as IEnumerable - && jToken["fieldsets"] != null && jToken["fieldsets"].Any()) - { - return DeserializeEnumerableObject(obj, jToken); + var obj = Activator.CreateInstance(objectType); + + if (null != obj as IEnumerable) + { + JToken enumerableToken; + + if (TryParseJTokenAsEnumerable(jToken, out enumerableToken) + || TryParseJTokenAsEnumerable(jToken["value"], out enumerableToken)) + return DeserializeEnumerableObject(obj, enumerableToken); } return null == jToken as JArray ? DeserializeObject(obj, jToken) : PopulateProperties(obj, jToken); + } + + private bool TryParseJTokenAsEnumerable(JToken jToken, out JToken resultToken) + { + resultToken = null; + var jTokenEnumerable = jToken != null && jToken["fieldsets"] != null && jToken["fieldsets"].Any(); + + if (jTokenEnumerable) + resultToken = jToken; + + return jTokenEnumerable; } public override bool CanConvert(Type objectType) @@ -84,9 +98,9 @@ namespace Archetype.Umbraco.Serialization foreach (var propInfo in asFieldset) { var propAlias = GetJsonPropertyName(propInfo); - var fsJToken = GetProperties(propInfo.PropertyType, jToken); + var fsJToken = GetPropertyToken(propInfo.PropertyType, jToken); var propJToken = - fsJToken.Single(p => p.SelectToken("alias").ToString().Equals(propAlias)); + fsJToken["properties"].Single(p => p.SelectToken("alias").ToString().Equals(propAlias)); if (propJToken == null) continue; @@ -94,19 +108,31 @@ namespace Archetype.Umbraco.Serialization var propValue = GetPropertyValue(propInfo, propJToken); propInfo.SetValue(obj, propValue); - } - - return PopulateProperties(obj, GetProperties(obj.GetType(), jToken)); + } + + var propToken = GetPropertyToken(obj.GetType(), jToken); + + return propToken == null + ? obj + : PopulateProperties(obj, propToken["properties"] ?? new JArray(propToken)); } - private JToken GetProperties(Type objType, JToken jToken) + private JToken GetPropertyToken(Type objType, JToken jToken) { var objAlias = GetFieldsetName(objType); if (jToken["fieldsets"] != null) - return jToken["fieldsets"].Single(p => p.SelectToken("alias").ToString().Equals(objAlias)).SelectToken("properties"); + return jToken["fieldsets"].Single(p => p.SelectToken("alias").ToString().Equals(objAlias)); - return jToken["alias"].ToString().Equals(objAlias) ? jToken.SelectToken("properties") : null; + if (jToken["value"] != null && jToken["value"].HasValues && jToken["value"]["fieldsets"] != null) + { + var fsJToken = jToken["value"]["fieldsets"].SingleOrDefault(p => p.SelectToken("alias").ToString().Equals(objAlias)); + if (fsJToken != null) + return fsJToken; + } + + + return jToken["alias"].ToString().Equals(objAlias) ? jToken : null; } private object PopulateProperties(object obj, JToken jToken) @@ -132,8 +158,8 @@ namespace Archetype.Umbraco.Serialization private object GetPropertyValue(PropertyInfo propertyInfo, JToken propJToken) { - return IsTypeArchetypeDatatype(propertyInfo.PropertyType) - ? JsonConvert.DeserializeObject(propJToken["value"].ToString(), propertyInfo.PropertyType, + return IsTypeArchetypeDatatype(propertyInfo.PropertyType) + ? JsonConvert.DeserializeObject(propJToken.ToString(), propertyInfo.PropertyType, this) : IsTypeIEnumerableArchetypeDatatype(propertyInfo.PropertyType) ? JsonConvert.DeserializeObject(propJToken["value"].SelectToken("fieldsets").ToString(), propertyInfo.PropertyType,