diff --git a/src/Umbraco.Core/Dynamics/DynamicDictionary.cs b/src/Umbraco.Core/Dynamics/DynamicDictionary.cs index 9aef032bc3..f3ab75413f 100644 --- a/src/Umbraco.Core/Dynamics/DynamicDictionary.cs +++ b/src/Umbraco.Core/Dynamics/DynamicDictionary.cs @@ -5,28 +5,29 @@ namespace Umbraco.Core.Dynamics { public class DynamicDictionary : DynamicObject { - readonly Dictionary _dictionary; + internal readonly Dictionary SourceItems; + public DynamicDictionary(Dictionary sourceItems) { - _dictionary = sourceItems; + SourceItems = sourceItems; } public override bool TrySetMember(SetMemberBinder binder, object value) { - if (_dictionary.ContainsKey(binder.Name)) + if (SourceItems.ContainsKey(binder.Name)) { - _dictionary[binder.Name.ToLower()] = value; + SourceItems[binder.Name.ToLower()] = value; } else { - _dictionary.Add(binder.Name.ToLower(), value); + SourceItems.Add(binder.Name.ToLower(), value); } return true; } public override bool TryGetMember(GetMemberBinder binder, out object result) { - if (_dictionary != null) + if (SourceItems != null) { - if (_dictionary.TryGetValue(binder.Name.ToLower(), out result)) + if (SourceItems.TryGetValue(binder.Name.ToLower(), out result)) { return true; } diff --git a/src/Umbraco.Core/Dynamics/DynamicXml.cs b/src/Umbraco.Core/Dynamics/DynamicXml.cs index 0cfc13e58c..80a3303a60 100644 --- a/src/Umbraco.Core/Dynamics/DynamicXml.cs +++ b/src/Umbraco.Core/Dynamics/DynamicXml.cs @@ -81,7 +81,7 @@ namespace Umbraco.Core.Dynamics } //Go ahead and try to fetch all of the elements matching the member name, and wrap them var elements = BaseElement.Elements(binder.Name); - if (elements.Count() == 0 && BaseElement.Name == "root" && BaseElement.Elements().Count() == 1) + if (!elements.Any() && BaseElement.Name == "root" && BaseElement.Elements().Count() == 1) { //no elements matched, lets try first child elements = BaseElement.Elements().ElementAt(0).Elements(binder.Name); diff --git a/src/Umbraco.Tests/DynamicDocument/DynamicXmlTests.cs b/src/Umbraco.Tests/DynamicDocument/DynamicXmlTests.cs index b302f27979..1d69b1f9cd 100644 --- a/src/Umbraco.Tests/DynamicDocument/DynamicXmlTests.cs +++ b/src/Umbraco.Tests/DynamicDocument/DynamicXmlTests.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics; using System.Xml; using System.Xml.Linq; using Microsoft.CSharp.RuntimeBinder; @@ -11,13 +12,41 @@ namespace Umbraco.Tests.DynamicDocument public class DynamicXmlTests { + [Test] + public void Ensure_Legacy_Objects_Are_Returned() + { + var xml = "/media/54/tulips.jpg1024768620888jpg/media/41/hydrangeas.jpg1024768595284jpg"; + var mediaItems = new global::umbraco.MacroEngines.DynamicXml(xml); + //Debug.WriteLine("full xml = {0}", mediaItems.ToXml()); + + if (mediaItems.Count() != 0) + { + foreach (dynamic item in mediaItems) + { + Type itemType = item.GetType(); + Debug.WriteLine("item type = {0}", itemType); + dynamic image = item.Image; + + Type imageType = image.GetType(); + Debug.WriteLine("image type = {0}", imageType); + + //ensure they are the same + Assert.AreEqual(itemType, imageType); + + //ensure they are legacy + Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), itemType); + Assert.AreEqual(typeof(global::umbraco.MacroEngines.DynamicXml), imageType); + } + } + } + /// /// Test the current Core class /// [Test] public void Find_Test_Core_Class() { - RunFindTest(x => new DynamicXml(x)); + RunFindTest(x => new DynamicXml(x)); } /// diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicDictionary.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicDictionary.cs index 1257149399..72c6b44726 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicDictionary.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicDictionary.cs @@ -22,7 +22,11 @@ namespace umbraco.MacroEngines } public override bool TryGetMember(GetMemberBinder binder, out object result) { - return _internal.TryGetMember(binder, out result); + var innerResult = _internal.TryGetMember(binder, out result); + //special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need + //to return the legacy type + result = LegacyConverter.ConvertToLegacy(result); + return innerResult; } } } diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNull.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNull.cs index 30f0d761b0..5628a755ff 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNull.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNull.cs @@ -40,15 +40,27 @@ namespace umbraco.MacroEngines } public override bool TryGetMember(GetMemberBinder binder, out object result) { - return _inner.TryGetMember(binder, out result); + var innerResult =_inner.TryGetMember(binder, out result); + //special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need + //to return the legacy type + result = LegacyConverter.ConvertToLegacy(result); + return innerResult; } public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { - return _inner.TryGetIndex(binder, indexes, out result); + var innerResult = _inner.TryGetIndex(binder, indexes, out result); + //special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need + //to return the legacy type + result = LegacyConverter.ConvertToLegacy(result); + return innerResult; } public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { - return _inner.TryInvoke(binder, args, out result); + var innerResult = _inner.TryInvoke(binder, args, out result); + //special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need + //to return the legacy type + result = LegacyConverter.ConvertToLegacy(result); + return innerResult; } public bool IsNull() { diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicXml.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicXml.cs index 0e3e2fec93..fa45127c52 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicXml.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicXml.cs @@ -11,7 +11,6 @@ using System.Web; namespace umbraco.MacroEngines { - [Obsolete("This class has been superceded by Umbraco.Core.Dynamics.DynamicXml")] public class DynamicXml : DynamicObject, IEnumerable { @@ -45,15 +44,27 @@ namespace umbraco.MacroEngines } public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) { - return _inner.TryGetIndex(binder, indexes, out result); + var innerResult = _inner.TryGetIndex(binder, indexes, out result); + //special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need + //to return the legacy type + result = LegacyConverter.ConvertToLegacy(result); + return innerResult; } public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { - return _inner.TryInvokeMember(binder, args, out result); + var innerResult = _inner.TryInvokeMember(binder, args, out result); + //special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need + //to return the legacy type + result = LegacyConverter.ConvertToLegacy(result); + return innerResult; } public override bool TryGetMember(GetMemberBinder binder, out object result) { - return _inner.TryGetMember(binder, out result); + var innerResult = _inner.TryGetMember(binder, out result); + //special case, we need to check if the result is of a non-legacy dynamic type because if it is, we need + //to return the legacy type + result = LegacyConverter.ConvertToLegacy(result); + return innerResult; } public DynamicXml XPath(string expression) diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/LegacyConverter.cs b/src/umbraco.MacroEngines/RazorDynamicNode/LegacyConverter.cs new file mode 100644 index 0000000000..209c246003 --- /dev/null +++ b/src/umbraco.MacroEngines/RazorDynamicNode/LegacyConverter.cs @@ -0,0 +1,29 @@ +namespace umbraco.MacroEngines +{ + internal static class LegacyConverter + { + /// + /// Checks if the object is DynamicXml or DynamicNull and ensures that we return the legacy class not the new one + /// as we want this class to always ensure we're dealing with the legacy classes + /// + /// + /// + internal static object ConvertToLegacy(object result) + { + if (result is Umbraco.Core.Dynamics.DynamicXml) + { + result = new DynamicXml(((Umbraco.Core.Dynamics.DynamicXml)result).BaseElement); + } + else if (result is Umbraco.Core.Dynamics.DynamicNull) + { + result = new DynamicNull(); + } + else if (result is Umbraco.Core.Dynamics.DynamicDictionary) + { + result = new DynamicDictionary(((Umbraco.Core.Dynamics.DynamicDictionary) result).SourceItems); + } + + return result; + } + } +} \ No newline at end of file diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj index ee3903ac40..51526ba146 100644 --- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj +++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj @@ -86,6 +86,7 @@ +