Sitecore – Changing the default Site Resolver pipeline

Solution Architect
Valtech North America

February 03, 2020

Every request made to a Sitecore website goes through a series of pipelines and processors before the user sees a response on their browser.

One of the first processors that kick in during the <httpBeginRequest> is

<processor type="Sitecore.Pipelines.HttpRequest.SiteResolver, Sitecore.Kernel"/>

Here is where Sitecore generates the “Context” for the request. What SiteResolver does is pretty straight forward, but super-critical.

siteresolver

Basically, it reads the <site> node attributes and cookies then sets up the SiteContext for the request. When the SiteContext is generated at this level, it is pretty much impossible to change the values in any subsequent processor. You can, however, update certain attributes of the SiteContext as needed for a much smaller scope. For instance, when fetching an item, you can change the context database from “web” to “master” or vice-versa. But this context for obvious reasons is not changed at a higher level (request level).

Here is a very simple example of how to change the SiteContext by adding a custom processor.

namespace Sitecore.Custom.Website.Infrastructure.Pipelines

{
    public class CustomSiteResolver : SiteResolver
    {
        public CustomSiteResolver():base()
        {
        }

        public CustomSiteResolver(BaseSiteContextFactory siteContextFactory) : base(siteContextFactory)
        {
        }
        protected CustomSiteResolver(BaseSiteContextFactory siteContextFactory, bool enableSiteConfigFiles) : base(siteContextFactory, enableSiteConfigFiles)
        {

        }
        public override void Process(HttpRequestArgs args)
        {
            SiteContext siteContext = ResolveSiteContext(args);
            if (HttpContext.Current.Request.Url.Host.ToLower().Contains("preview") && siteContext.Database.Name=="web")
            {
                Database database = Factory.GetDatabase("master");
                siteContext.Database = database;
            }
            UpdatePaths(args, siteContext);
            SetSiteToRequestContext(siteContext);
        }
    }
}

Code walkthrough…

The safest option, and the option that requires much lesser code, is to basically inherit from the already existing processor, in this case SiteResolver class.

Advantages:
  1. You can fallback to base implementation
  2. You don’t have to redefine all the core processing that the base would be doing
  3. More importantly, you don’t change anything which you don’t know for sure 😊

In the above example, the only difference between what Sitecore does by default and what I changed is simply the bolded/


code. I want a preview site and when somebody access my preview site with the required “hostname” (in my case I was using “preview.local” as the hostname), I serve content from the “master” instead of the “web” database.

As with all Sitecore processors, you must define the patch configuration to ensure that the pipeline gets called. Here is the sample to show how that is done:

<configuration>
  <sitecore>
    <pipelines>
      <httpRequestBegin>
        <processor type="Sitecore.Custom.Website.Infrastructure.Pipelines.CustomSiteResolver, Sitecore.Custom.Website" patch:instead="processor[@type='Sitecore.Pipelines.HttpRequest.SiteResolver, Sitecore.Kernel']" />
      </httpRequestBegin>
    </pipelines>
    <sites>
      <site name="storefront">        
        <patch:attribute name="hostName">preview.local|mainwebsite.local</patch:attribute>
      </site>            
    </sites>
  </sitecore>
</configuration>

This can be further restricted based on your needs to fire only within certain environments (using Sitecore role configuration) or change the condition to meet your specific needs.

Contact us

We would love to hear from you! Please fill out the form and the nearest person from office will contact you.

Let's reinvent the future