Fixes more of U4-1140, ensure that only legacy objects are returned from the dynamic stuff in the razor macros. Adds unit test for it.
This commit is contained in:
@@ -5,28 +5,29 @@ namespace Umbraco.Core.Dynamics
|
||||
{
|
||||
public class DynamicDictionary : DynamicObject
|
||||
{
|
||||
readonly Dictionary<string, object> _dictionary;
|
||||
internal readonly Dictionary<string, object> SourceItems;
|
||||
|
||||
public DynamicDictionary(Dictionary<string, object> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 = "<DAMP fullMedia=\"\"><mediaItem><Image id=\"1057\" version=\"d58d5c16-153e-4896-892f-a722e45a69af\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:55:29\" updateDate=\"2012-11-05T16:55:44\" nodeName=\"test12\" urlName=\"test12\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1057\"><umbracoFile>/media/54/tulips.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>620888</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:55:34\"><crop name=\"thumbCrop\" x=\"154\" y=\"1\" x2=\"922\" y2=\"768\" url=\"/media/54/tulips_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem><mediaItem><Image id=\"1055\" version=\"4df1f08a-3552-45f2-b4bf-fa980c762f4a\" parentID=\"-1\" level=\"1\" writerID=\"0\" nodeType=\"1032\" template=\"0\" sortOrder=\"1\" createDate=\"2012-11-05T16:29:58\" updateDate=\"2012-11-05T16:30:27\" nodeName=\"Test\" urlName=\"test\" writerName=\"admin\" nodeTypeAlias=\"Image\" path=\"-1,1055\"><umbracoFile>/media/41/hydrangeas.jpg</umbracoFile><umbracoWidth>1024</umbracoWidth><umbracoHeight>768</umbracoHeight><umbracoBytes>595284</umbracoBytes><umbracoExtension>jpg</umbracoExtension><newsCrops><crops date=\"2012-11-05T16:30:18\"><crop name=\"thumbCrop\" x=\"133\" y=\"0\" x2=\"902\" y2=\"768\" url=\"/media/41/hydrangeas_thumbCrop.jpg\" /></crops></newsCrops></Image></mediaItem></DAMP>";
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test the current Core class
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void Find_Test_Core_Class()
|
||||
{
|
||||
RunFindTest(x => new DynamicXml(x));
|
||||
RunFindTest(x => new DynamicXml(x));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
29
src/umbraco.MacroEngines/RazorDynamicNode/LegacyConverter.cs
Normal file
29
src/umbraco.MacroEngines/RazorDynamicNode/LegacyConverter.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace umbraco.MacroEngines
|
||||
{
|
||||
internal static class LegacyConverter
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
/// </summary>
|
||||
/// <param name="result"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,6 +86,7 @@
|
||||
<Compile Include="RazorDynamicNode\DynamicBackingItem.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicBackingItemType.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicClass.cs" />
|
||||
<Compile Include="RazorDynamicNode\LegacyConverter.cs" />
|
||||
<Compile Include="RazorDynamicNode\PublishedContentExtensions.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicExpression.cs" />
|
||||
<Compile Include="RazorDynamicNode\DynamicGrouping.cs" />
|
||||
|
||||
Reference in New Issue
Block a user