From b367f63c1d09cfd31d49093e2276974396187df3 Mon Sep 17 00:00:00 2001 From: "agrath@gmail.com" Date: Sun, 12 Jun 2011 11:21:44 -0200 Subject: [PATCH] Fixed null reference problems with new dynamicbackingitem Fixed recursive property null reference problems Fixed issue with node having no children and property check crashing Made DynamicXml behave more consistently based on user feedback Added IsNull and HasValue to PropertyResult (comes back from GetProperty but you may need to cast it) Added new Model.IsNull(string alias, bool recursive) and Model.HasValue(string alias, bool recursive) and Model.IsNull(string alias) and Model.HasValue(string alias) --- .../RazorDynamicNode/DynamicBackingItem.cs | 20 +++++++++- .../RazorDynamicNode/DynamicNode.cs | 39 +++++++++++++------ .../RazorDynamicNode/DynamicNodeContext.cs | 13 +++++-- .../RazorDynamicNode/DynamicXml.cs | 30 +++++--------- .../RazorDynamicNode/PropertyResult.cs | 18 +++++++-- 5 files changed, 78 insertions(+), 42 deletions(-) diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicBackingItem.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicBackingItem.cs index 5e7e63a34f..48b4a408e0 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicBackingItem.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicBackingItem.cs @@ -51,7 +51,7 @@ namespace umbraco.MacroEngines public bool IsNull() { - return ((Type == DynamicBackingItemType.Content && content == null) || media == null); + return (content == null && media == null); } public List ChildrenAsList { @@ -81,7 +81,23 @@ namespace umbraco.MacroEngines public IProperty GetProperty(string alias) { if (IsNull()) return null; - return Type == DynamicBackingItemType.Content ? new PropertyResult(content.GetProperty(alias)) : new PropertyResult(media.GetProperty(alias)); + if (Type == DynamicBackingItemType.Content) + { + var prop = content.GetProperty(alias); + if (prop != null) + { + return new PropertyResult(prop); + } + } + else + { + var prop = media.GetProperty(alias); + if (prop != null) + { + return new PropertyResult(prop); + } + } + return null; } public IProperty GetProperty(string alias, out bool propertyExists) { diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs index 4aba0c6a84..434fb90b0e 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNode.cs @@ -389,8 +389,10 @@ namespace umbraco.MacroEngines //check if the alias is that of a child type - var typeChildren = n.ChildrenAsList - .Where(x => + var typeChildren = n.ChildrenAsList; + if (typeChildren != null) + { + var filteredTypeChildren = typeChildren.Where(x => { List ancestorAliases = GetAncestorOrSelfNodeTypeAlias(x); if (ancestorAliases == null) @@ -399,10 +401,12 @@ namespace umbraco.MacroEngines } return ancestorAliases.Any(alias => alias == name || MakePluralName(alias) == name); }); - if (typeChildren.Any()) - { - result = new DynamicNodeList(typeChildren); - return true; + if (filteredTypeChildren.Any()) + { + result = new DynamicNodeList(filteredTypeChildren); + return true; + } + } try @@ -1042,8 +1046,8 @@ namespace umbraco.MacroEngines while (prop == null) { context = context.Parent; - prop = context.GetProperty(alias); if (context == null) break; + prop = context.GetProperty(alias); } if (prop != null) { @@ -1075,14 +1079,25 @@ namespace umbraco.MacroEngines if (n == null) return null; return n.ChildrenAsTable(nodeTypeAliasFilter); } - - public bool IsNull() + public bool IsNull(string alias, bool recursive) { - return false; + var prop = GetProperty(alias); + if (prop == null) return true; + return (prop as PropertyResult).IsNull(); } - public bool HasValue() + public bool IsNull(string alias) { - return true; + return IsNull(alias, false); + } + public bool HasValue(string alias) + { + return HasValue(alias, false); + } + public bool HasValue(string alias, bool recursive) + { + var prop = GetProperty(alias); + if (prop == null) return false; + return (prop as PropertyResult).HasValue(); } public int Position() { diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeContext.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeContext.cs index fa9affddf3..70ff6fb18b 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeContext.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicNodeContext.cs @@ -2,16 +2,21 @@ using umbraco.cms.businesslogic.macro; using umbraco.interfaces; -namespace umbraco.MacroEngines { +namespace umbraco.MacroEngines +{ - public abstract class DynamicNodeContext : BaseContext { + public abstract class DynamicNodeContext : BaseContext + { - public override void SetMembers(MacroModel macro, INode node) { + public override void SetMembers(MacroModel macro, INode node) + { if (macro == null) throw new ArgumentNullException("macro"); if (node == null) throw new ArgumentNullException("node"); - CurrentModel = new DynamicNode(node); + var backingItem = new DynamicBackingItem(node); + var dynamicNode = new DynamicNode(backingItem); + CurrentModel = dynamicNode; base.SetMembers(macro, node); } diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicXml.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicXml.cs index a841cfc007..587c4c724f 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicXml.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/DynamicXml.cs @@ -86,9 +86,16 @@ namespace umbraco.MacroEngines int count = elements.Count(); if (count > 0) { - if (count > 1) + var firstElement = elements.FirstOrDefault(); + //we have a single element, does it have any children? + if (firstElement != null && firstElement.Elements().Count() == 0 && !firstElement.HasAttributes) + { + //no, return the text + result = firstElement.Value; + return true; + } + else { - //result = elements; //We have more than one matching element, so let's return the collection //elements is IEnumerable //but we want to be able to re-enter this code @@ -100,25 +107,6 @@ namespace umbraco.MacroEngines //or you use [] indexing and you end up with a single element return true; } - else - { - var firstElement = elements.FirstOrDefault(); - //we have a single element, does it have any children? - if (firstElement.Elements().Count() == 0) - { - //no, return the text - result = firstElement.Value; - return true; - } - else - { - //yes return this element wrapped in DynamicXml - result = new DynamicXml(firstElement); - //There is only one matching element, so let's just return it - return true; - } - } - return true; //return true cuz we matched } result = null; return false; diff --git a/umbraco.MacroEngines.Juno/RazorDynamicNode/PropertyResult.cs b/umbraco.MacroEngines.Juno/RazorDynamicNode/PropertyResult.cs index afe5b79548..bc8b179b80 100644 --- a/umbraco.MacroEngines.Juno/RazorDynamicNode/PropertyResult.cs +++ b/umbraco.MacroEngines.Juno/RazorDynamicNode/PropertyResult.cs @@ -15,9 +15,12 @@ namespace umbraco.MacroEngines public PropertyResult(IProperty source) { - this._alias = source.Alias; - this._value = source.Value; - this._version = source.Version; + if (source != null) + { + this._alias = source.Alias; + this._value = source.Value; + this._version = source.Version; + } } public PropertyResult(string alias, string value, Guid version) { @@ -45,5 +48,14 @@ namespace umbraco.MacroEngines { get { return _version; } } + + public bool IsNull() + { + return Value == null; + } + public bool HasValue() + { + return !string.IsNullOrWhiteSpace(Value); + } } }