From 8be92d8ed131c47802556c59375d622dc9f5b49a Mon Sep 17 00:00:00 2001 From: Shad Storhaug Date: Mon, 12 May 2014 01:37:18 +0700 Subject: [PATCH] Added IEquality to the ISiteMapNode type, and override Equals, ==, !=, GetHashCode, and ToString on SiteMapNode, so the equality check uses the Key of the node if the memory location is different, as discussed in #310. --- .../Unit/Web/Html/FakeSiteMapNode.cs | 10 +++ .../Builder/ReflectionSiteMapBuilder.cs | 4 +- .../MvcSiteMapProvider/ISiteMapNode.cs | 2 +- .../MvcSiteMapProvider/SiteMapNode.cs | 61 +++++++++++++++++++ .../SiteMapNodePositioningBase.cs | 4 +- .../SiteMapNodeSecurityBase.cs | 1 + .../Web/Html/Models/SiteMapNodeModel.cs | 6 +- 7 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider.Tests/Unit/Web/Html/FakeSiteMapNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider.Tests/Unit/Web/Html/FakeSiteMapNode.cs index c73b9161..b8b3e238 100644 --- a/src/MvcSiteMapProvider/MvcSiteMapProvider.Tests/Unit/Web/Html/FakeSiteMapNode.cs +++ b/src/MvcSiteMapProvider/MvcSiteMapProvider.Tests/Unit/Web/Html/FakeSiteMapNode.cs @@ -324,6 +324,16 @@ public void CopyTo(ISiteMapNode node) throw new NotImplementedException(); } + public bool Equals(ISiteMapNode node) + { + if (base.Equals(node)) + { + return true; + } + + return this.Key.Equals(node.Key); + } + #endregion } diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs index c6bf56ae..a6683a40 100644 --- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs +++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Builder/ReflectionSiteMapBuilder.cs @@ -283,7 +283,7 @@ protected virtual ISiteMapNode CreateNodesFromMvcSiteMapNodeAttributeDefinitions foreach (var dynamicNode in dynamicNodesForChildNode) { // Verify parent/child relation - if (dynamicNode.ParentNode == parentNode + if (dynamicNode.ParentNode.Equals(parentNode) && !siteMap.GetChildNodes(parentNode).Contains(dynamicNode)) { siteMap.AddNode(dynamicNode, parentNode); @@ -325,7 +325,7 @@ protected virtual ISiteMapNode CreateNodesFromMvcSiteMapNodeAttributeDefinitions foreach (var dynamicNode in dynamicNodesForChildNode) { // Verify parent/child relation - if (dynamicNode.ParentNode == parentNode + if (dynamicNode.ParentNode.Equals(parentNode) && !siteMap.GetChildNodes(parentNode).Contains(dynamicNode)) { siteMap.AddNode(dynamicNode, parentNode); diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs index 770dbff7..1f26c354 100644 --- a/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs +++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/ISiteMapNode.cs @@ -11,7 +11,7 @@ namespace MvcSiteMapProvider /// node in the hierarchy. /// public interface ISiteMapNode - : ISortable + : ISortable, IEquatable { string Key { get; } bool IsDynamic { get; } diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs index c305b35b..1838e3c0 100644 --- a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs +++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNode.cs @@ -775,5 +775,66 @@ public override void CopyTo(ISiteMapNode node) } #endregion + + #region IEquatable Members + + public override bool Equals(ISiteMapNode node) + { + if (base.Equals((object)node)) + { + return true; + } + + return this.Key.Equals(node.Key); + } + + #endregion + + #region System.Object Overrides + + public override bool Equals(object obj) + { + ISiteMapNode node = obj as ISiteMapNode; + if (node == null) + { + return false; + } + + return this.Equals(node); + } + + public static bool operator ==(SiteMapNode node1, SiteMapNode node2) + { + // If both are null, or both are same instance, return true. + if (object.ReferenceEquals(node1, node2)) + { + return true; + } + + // If one is null, but not both, return false. + if (((object)node1 == null) || ((object)node2 == null)) + { + return false; + } + + return node1.Equals(node2); + } + + public static bool operator !=(SiteMapNode node1, SiteMapNode node2) + { + return !(node1 == node2); + } + + public override int GetHashCode() + { + return this.Key.GetHashCode(); + } + + public override string ToString() + { + return this.Key; + } + + #endregion } } diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodePositioningBase.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodePositioningBase.cs index 79e7967f..b407a980 100644 --- a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodePositioningBase.cs +++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodePositioningBase.cs @@ -150,8 +150,6 @@ protected virtual ISiteMapNodeCollection SiblingNodes } } - // TODO: rework... (maartenba) - /// /// Determines whether the specified node is in current path. /// @@ -161,7 +159,7 @@ protected virtual ISiteMapNodeCollection SiblingNodes public override bool IsInCurrentPath() { ISiteMapNode node = this; - return (this.SiteMap.CurrentNode != null && (node == this.SiteMap.CurrentNode || this.SiteMap.CurrentNode.IsDescendantOf(node))); + return (this.SiteMap.CurrentNode != null && (this.SiteMap.CurrentNode.Equals(node) || this.SiteMap.CurrentNode.IsDescendantOf(node))); } /// diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs index 63360eb6..e85a1c04 100644 --- a/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs +++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/SiteMapNodeSecurityBase.cs @@ -92,6 +92,7 @@ public virtual bool IsAccessibleToUser() public abstract string Controller { get; set; } public abstract string Action { get; set; } public abstract void CopyTo(ISiteMapNode node); + public abstract bool Equals(ISiteMapNode node); #endregion } diff --git a/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/Html/Models/SiteMapNodeModel.cs b/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/Html/Models/SiteMapNodeModel.cs index 6eb82c5f..dd5fa177 100644 --- a/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/Html/Models/SiteMapNodeModel.cs +++ b/src/MvcSiteMapProvider/MvcSiteMapProvider/Web/Html/Models/SiteMapNodeModel.cs @@ -54,9 +54,9 @@ public SiteMapNodeModel(ISiteMapNode node, IDictionary sourceMet Url = node.Url; CanonicalUrl = node.CanonicalUrl; MetaRobotsContent = node.GetMetaRobotsContentString(); - IsCurrentNode = (node == node.SiteMap.CurrentNode); + IsCurrentNode = (node.Equals(node.SiteMap.CurrentNode)); IsInCurrentPath = node.IsInCurrentPath(); - IsRootNode = (node == node.SiteMap.RootNode); + IsRootNode = (node.Equals(node.SiteMap.RootNode)); IsClickable = node.Clickable; VisibilityAffectsDescendants = visibilityAffectsDescendants; RouteValues = node.RouteValues; @@ -347,7 +347,7 @@ private bool ReachedMaximalNodelevel(int maxDepth, ISiteMapNode node, bool drill return false; if (node.IsInCurrentPath()) return true; - if (node.ParentNode == node.SiteMap.CurrentNode) + if (node.ParentNode != null && node.ParentNode.Equals(node.SiteMap.CurrentNode)) return true; foreach (ISiteMapNode sibling in node.ParentNode.ChildNodes) {