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…
[su_note note_color=”#fafafa”]Today I learned that a controller responding to a route registered via MVC attribute routing will generate a not tracked experience[/su_note]
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 theinitialize
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 themvc.requestBegin
andmvc.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 theStopRoutingHandler
.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 StopRoutingHandlerThat 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!
[su_divider][/su_divider]
Please leave a comment if you have dealt with it and/or see what I might be missing.