Attribute Routing and xDB Tracking

Attribute Routing

Rumor has it: you can use MVC attribute routing in Sitecore. It’s actually very easy to set up. John West posted it recently on his blog. Today I stumbled upon an interesting side effect of using this way of routes registration that may be important if your controllers generate user facing experiences that you want to track.

Tracking

The way we track pages is fairly simple. Drop one line in the head of your layout document and XP/xDB/DMS will track your visit:

@Html.Sitecore().VisitorIdentification()

Without the magic line your visit will be seen as not worthy of tracking – Sitecore is convinced that everyone is a robot unless proven otherwise.

Oops…

Today I learned that a controller responding to a route registered via MVC attribute routing will generate a not tracked experience

I am using the technique I blogged about previously to build a dynamic product details page (part 1, part 2, part 3) and this time I wanted to make sure these URLs are tracked. Running the following line in my layout document kept reporting Not Active for attribute routed controllers and Active for manually registered routes:

<strong>Tracker: </strong> @(Sitecore.Analytics.Tracker.Current != null ? "Active" : "Not Active")

Why

In order to answer why I need to explain how Sitecore wires in your routes with its own way of handling MVC requests. Sitecore runs the InitializeRoutes processor as part of the initialize pipeline. That guy will register the default Sitecore controller and will also add custom handlers to all previously registered routes (and that’s why you want all your routes registered before this guy runs). These custom handlers attach the mvc.requestBegin and mvc.requestEnd pipelines to your routes so that when MVC engine takes over it doesn’t go too far without Sitecore knowing. And this is how you get all the tracking and everything else activated for those requests.

Now. That processor skips over certain things when reading through the routing table. It does skip over anything that doesn’t quack like a duck (I mean, everything that doesn’t respond to is Route) and it also skips over things that respond to the StopRoutingHandler.

Guess what. Routes registered with attribute routing appear to all have that. I don’t yet know why but I am right now looking at a route that has it. I ran the same logic that Sitecore uses when attaching custom handlers and here’s what it said:

6480 22:25:55 INFO  Will register route sclapi/{action}/{id} with MVC pipelines
6480 22:25:55 INFO  Will register route Remote/{*resource} with MVC pipelines
6480 22:25:55 INFO  Will register route sitecore/shell/Applications/SitecoreApps/RemoteSoapRequest.aspx with MVC pipelines
6480 22:25:55 INFO  Will register route api/sitecore/{controller}/{action} with MVC pipelines
6480 22:25:55 INFO  Will  NOT register route System.Web.Mvc.Routing.RouteCollectionRoute with MVC pipelines due to it not being a Route
6480 22:25:55 INFO  Will  NOT register route pavel/testing/{routes} with MVC pipelines due to StopRoutingHandler

That last guy has been registered with an attribute. If I change the registration to the good old MapRoute it all works fine.

What to do

First, I need to understand why a route registered via attributes received a StopRoutingHandler handler and the same route registered the old way did not.

Then, if confirmed that I am not doing anything wrong and am not missing anything, I would probably patch the InitializeRoutes to also wire the attribute routed controllers with the custom handlers. Or, alternatively, I could send an email to Kern (@herskinduk) and Kevin (@KevinObee) and see if the guys can do something for the upcoming 8.1. Another rumor has it that it’s imminent. Who knew!

To be continued!

Please leave a comment if you have dealt with it and/or see what I might be missing.

Pavel Veller

Add a Comment

Your email address will not be published. Required fields are marked *

Or request call back