Dynamic Routing with Kentico MVC - Service Pack (v3) Launched!


What's finished?  The Final Rendition of Dynamic Routing.  As you know, I've already posted article after article on Dynamic Routing.  And of all my articles, these two have gotten the most page views.  We were all disappointed when Kentico 12 didn't have Dynamic Routing built in, and I can't stand seeing our Kentico developers cry, so I set out to figure out this whole Dynamic Routing thing.

I first created a proof of concept article, then updated and published a guide on Dynamically Routing based on the NodeAliasPath being the Url Pattern for a page (since otherwise there was no way to know what page the user was requesting based on the Url).  However, there were limits to this system.  It didn't handle Culture Codes in the Url very well, it also didn't support anything BUT NodeAliasPath (lame), and also required manually adjusting some code method to update it's functionality (a total bummer).

What stunk was that Kentico announced that after the Service Pack they were not going to release any more major updates to Kentico 12, and with Kentico 2020 still a very long way away, I knew I needed to take things into my own hands once more, I began working with Kentico to create a Kentico 12 Dynamic Routing system that would line up with Kentico's Dynamic Routing for 2020 (which may or may not be based on this module, they didn't say yet).

The A-Team

Let's face it, when people think of MVC Champion, my name doesn't even come up in the running.  I needed some help, someone who is passionate about the Kentico community, and who has written a 15 17 part blog series on best practices with MVC and Kentico.  There is only one person who has written a 17 part blog series, and that person was Sean G. Wright!

So with the team assembled, we got to work.

What do we need?  Url Slugs!  

A Url Slug is the link between a Url and the page it belongs to.  These are often used in various CMS systems to facilitate dynamic routing.  Kentico had the system to generate the Url for a page (Page Type's Url Pattern), but this Url was not stored anywhere, so you could do a reverse lookup.  So the first (and biggest) part of the module is the Url Slug Generation System.

I won't bore you with the details, so I'll summarize what the module does.  It handles automatically generating the Url Slugs for pages, including creating Alternate Urls of old Url Slugs so your previous links do not break.  This system also overwrites the TreeNode.RelativeUrl and TreeNode.AbsoluteUrl, which Kentico uses for the preview functionality.  

The Url Slug generation also needed to be fast, handle conflicts, and work with things like version control, staging, changes in culture, order, anything.  My system does that!  And it's fast too!  It does most operations asyncly so you don't have to wait.

Custom Urls?  Yes Please!

Another big win with this tool is you now have the ability to set a Custom Url for a page, so you can finally create those vanity Urls you've been wanting.  

Did you get your {% Parent() %}'s Permission?

One last feature I added in was a new Macro for your Url Patterns, {% Parent() %}.  When you place this in your Url Pattern for your class, it will take the Url Slug of that page's parent, and place it there, so if you want a page's Url to be the Parent's + that pages NodeAlias, you could put {% Parent() %}/{% NodeAlias %}.

MVC Magic

DynamicRoutingHelper.GetPage() - We Love You

The next part of the magic is in the DynamicRoutingHelper.GetPage() function.  This handy little method takes the current request, and gets you the page!  You don't even have to lift a finger [except to type]!  But that's not all!  It automatically handles if it's in Preview Mode or not (loading the current document version and the correct culture), handles caching, and you can pass it a column list to get the specified columns.

Routing as Simple or Complex as You Want!

You know what I love about building Page Builder Sections, Widgets, and Page Templates in Kentico?  You can go as simple or complex as you want.  You can have it just be a simple View, or a View with your model, or you can pass it to a full blown Controller to do whatever crazy things you want.

Well now you can do that with Pages too!  The DynamicRouting attribute has multiple variations.  You can automatically route found pages to:

  • A Controller (Index Action)
  • A Controller + Specified Action
  • A View + ITreeNode model
  • A View + YourPageType's Model (so you have a strongly typed Model)
  • A View with no model.
Failed to load widget object.
The file '/CMSWebParts/Custom/HighlightJS/HighlightJS.ascx' does not exist.

For the View/View+Models, the PageBuilder is automatically initialized for you as well!

Page Template Handling and Empty.Template

Page templates are also automatically handled by the Dynamic Routing.  If your page uses a page template, it will be handled as you would expect, sending the request to that Page Template itself.

I've also included an Empty.Template page template that fixes an issue where if you have Page Templates, you MUST select one.  Now you can elect to not select any Page Template if you wish the page to be routed normally.  There are two page template filters that you can apply to either enable or disable this feature.

Why are you still reading this?

Seriously, do I need to say any more?  Head to the GitHub repo and follow the easy instructions and start using this today!  And don't forget to drop Sean or I a line on what you think, this was a huge labor of love and we love hearing feedback.

Hi Trevor,

Good job. This is very useful for Kentico MVC devs.

I'm trying to use the View + Typed Model routing with something like this:
[assembly: DynamicRouting("~/Views/Contact/Details.cshtml", typeof(Contact), Contact.CLASS_NAME)]

However, I always get "System.InvalidCastException: Object must implement IConvertible."

Apparently the type conversion from a TreeNode within RenderViewWithModel() cannot be made.

Any idea what am I doing wrong, or what do I should check?

Thanks in advance.
Kind regards,
1/24/2020 11:22:47 AM

Hi Trevor, Thank so much for this components it really helps a lot

12/11/2019 12:12:07 AM

Is two = seven ? (true/false)