Trackable
Your page visits are trackable thanks to this:
<mvc.requestBegin patch:source="Sitecore.Mvc.config"> <processor type="Sitecore.Mvc.Pipelines.Request.RequestBegin.SetupPageContext, Sitecore.Mvc"/> <processor type="Sitecore.Mvc.Pipelines.Request.RequestBegin.ExecuteFormHandler, Sitecore.Mvc"/> <processor type="Sitecore.Mvc.Analytics.Pipelines.MvcEvents.RequestBegin.StartTracking, Sitecore.Mvc.Analytics"/> ... </mvc.requestBegin>
Your MVC routes registered via:
context.Routes.MapRoute("ProductDetailsPage", "product-catalog/product/{id}", new { controller = "ProductDetailsPage", action = "Index" });
are trackable thanks to this code in Sitecore.Mvc.Pipelines.Loader.InitializeRoutes
(part of the initialize
pipeline):
foreach (RouteBase routeBase in (Collection<RouteBase>) routes) { Route route = routeBase as Route; if (route != null) { IRouteHandler routeHandler = route.RouteHandler; if (routeHandler != null && !(routeHandler is StopRoutingHandler)) { route.RouteHandler = new RouteHandlerWrapper(routeHandler); } } }
where the custom handler wires in the MVC pipelines:
protected virtual void BeginRequest() { PipelineService.Get().RunPipeline("mvc.requestBegin", new RequestBeginArgs(this.RequestContext)); } protected virtual void EndRequest() { PipelineService.Get().RunPipeline("mvc.requestEnd", new RequestEndArgs()); }
Untrackable
Your MVC routes with the attribute routing are not trackable. I blogged about it before. You can help it by running the tracker yourself:
if (!Tracker.IsActive) { Tracker.StartTracking(); }
Your Web API routes are not trackable either. This also includes your Sitecore.Services.Client routes. Trying to run the same Tracker.StartTracking()
code won’t help you this time though.
If you try to start tracking in your SSC controller it won’t activate the tracker and the log file will have a stack trace from analytics complaining about not being able to grab a session.
Session Aware
There are good reasons Web API is session-less by default. I get it but I also want the promise of xDB. I can do GA from the client but I already have all the details coming into my controllers in Sitecore. xDB won’t track it for me if I don’t give it a session so that’s what we will do – we will make SSC routes session aware.
SSC entity services are all handled by a single route:
HttpRouteCollectionExtensions.MapHttpRoute( config.Routes, "EntityService", this._routeBase + "{namespace}/{controller}/{id}/{action}", new { id = RouteParameter.Optional, action = "DefaultAction" } );
If we get a hold of this route at the right time we can give it a session aware route handler via IRequiredSessionState
:
public class MakeEntityServiceSessionAware { public void Process(PipelineArgs args) { var route = RouteTable.Routes["EntityService"] as Route; if (route != null) { route.RouteHandler = new SessionRouteHandler(); } } } public class SessionRouteHandler : IRouteHandler { IHttpHandler IRouteHandler.GetHttpHandler(RequestContext requestContext) { return new SessionControllerHandler(requestContext.RouteData); } } public class SessionControllerHandler : HttpControllerHandler, IRequiresSessionState { public SessionControllerHandler(RouteData routeData) : base(routeData) { } }
The right time is during initialize
pipeline right after SSC routes registration. Please always remember to ask nicely:
<pipelines> <initialize> <processor patch:after="...Sitecore.Services.Infrastructure.Sitecore.Pipelines.ServicesWebApiInitializer..." type="Please.MakeEntityServiceSessionAware" /> </initialize> </pipelines>
Coming Up Next
The untrackable is now trackable. Starting the tracker manually takes very little effort but we also had to make all entity service calls session aware. The latter makes me feel a little uneasy. I don’t mind HTTP session in my own controllers but I am not so sure about everybody else (e.g. all the built-in SSC controllers for analytics dashboard, path analyzer, and FXM, for example). I will definitely ask @KevinObee.
Next time I will show you how you can very elegantly record details about your AJAX endpoints – MVC and Web API alike – and we will talk about the nuances of xDB Page Events.
Stay tuned!
The idea to use a custom RouteHandler
to enable HTTP session in a Web API controller came from this blog post by @filip_woj.