Using Umbraco Virtual Nodes Package and your own URL Provider

A quick note on the order of URL Providers

I recently had to install the awesome Virtual Nodes Umbraco package into an existing project. This existing project, however already had a custom URL Provider in place to create custom URLs for downloads.

When I first installed the package, I went through the supporting docs and configured everything, then with fingers crossed, I ran the project and attempted to move an existing page beneath the newly created virtual node.

My existing page started with a URL of "/campaign-page", and I hoped that after the move the URL would be the same, but unfortunately it wasn't. The page was now showing with the URL or "/virtual-container/campaign-page". Noooooooooooo! Why can't things be simple!

Well, I fired up a clean Umbraco install with the starter kit and repeated the process of installing and configuring Virtual Nodes.... low and behold it worked! Damn it, that means something in my project is conflicting!

A bit of investigation later

So, to be clear, I had completely forgotten that this project had an existing UrlProvider in it. So after getting the package working in a clean install I returned to the project and thought carefully about what could be causing the problem. On the off-chance, I did a solution wide search for "UrlProvider" and low and behold there was a hit. The project had a custom URL provider in it that was being injected into the UrlProvider collection at index point 0.

The Solution

To get these two URL Providers working together the order in which they were registered was important. I needed the Virtual URL Provider to be registered first and then I could insert mine afterwards.

I updated my composer that was registering the original one with the following amends:

[ComposeAfter(typeof(DotSee.VirtualNodes.UrlProviderStartUp))]
public class RegisterUrlProviderComposer : IUserComposer
{
     public void Compose(Composition composition)
     {
         composition.UrlProviders()
              .InsertAfter<DotSee.VirtualNodes.VirtualNodesUrlProvider, 
                          MyUrlProvider>();
     }
}

With these changes, both the Virtual URL Provider and my existing custom URL Provider worked as expected.