ASP.NET MVC 2 RoutingEngineSiteMapProvider

Continuing my thought on RoutingEngineSiteMapProvider, I worked with Rob Seder on Sunday for a bit

I was thinking of Maarten Balliau’s solution on CodePlex to a MVCSiteMapProvider and was wondering if there is an easier way. We tried inheriting from StaticSiteMapProvider and copy/pasting the code from XmlSiteMapProvider and re-writing it(like Maarten did), created our own implementation for the SiteMapProvider, and then giving up.

That afternoon I then looked at inheriting from XMLSiteMapProvider and intercepting the NodeCreation to plug in a MvcSiteMapNode.  I just created a basic node like so:

        public MvcSiteMapNode(SiteMapProvider provider, string key, string url, string title, string description, IList roles, NameValueCollection attributes, NameValueCollection explicitResourceKeys, string implicitResourceKey):

            base(provider, key, url, title, description,roles,attributes,explicitResourceKeys,implicitResourceKey)

        {

        }

 

        public string Controller { get; set; }

        public string Action { get; set; }

 

The rest of the constructiors were omitted for brevity

I then tried to intercept the call in BuildSiteMap method. 

    public class RoutingEngineSiteMapProvider: XmlSiteMapProvider

    {

        public override SiteMapNode BuildSiteMap()

        {

            SiteMapNode siteMapNode = base.BuildSiteMap();

            MvcSiteMapNode mvcSiteMapNode = ConvertSiteMapNodeIntoMvcSiteMapNode(siteMapNode);

            return mvcSiteMapNode;

        }

 

        private MvcSiteMapNode ConvertSiteMapNodeIntoMvcSiteMapNode(SiteMapNode siteMapNode)

        {

            MvcSiteMapNode mvcSiteMapNode = new MvcSiteMapNode(siteMapNode.Provider,siteMapNode.Key,

                siteMapNode.Url,siteMapNode.Title, siteMapNode.Description);

 

            mvcSiteMapNode.Controller = "Test Controller";

            mvcSiteMapNode.Action = "Test Action";

 

            return mvcSiteMapNode;

        }

    }

 

Surprisingly, it worked.  However, when I went to add a line to check on the nodes themselves in BuildSiteMapNode() like this:

            int counter = mvcSiteMapNode.ChildNodes.Count;

 

Things went bad – Stack Overflow.  I was in recursive hell.

I then tried to intercept AddNode like this:

        protected override void AddNode(SiteMapNode node)

        {

            base.AddNode(node);

        }

 

The problem is that this method is not called when I spun up the site.

Grrrr… I am out of patience on this.  Looking at the code in Reflector makes me appreciate best practices all that more.  Node6  Microsoft, really?  What happens if there is a 7th level node?  No exception is thrown.

The last thing I can think of is to copy/paste the code in BuildSiteMap() and then getting rid of the XMLReader completely.  However, this would be a mucho breaking change because the method violates the Open/Closed Principle and the IoC tenant and I really don’t have the time to track down all of the dangling dependencies in this API.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: