Sitecore, SiteContext and Context.Database, oh my!

In my recent blog post about why my items were not returned from the Sitecore database, I mentioned that you should always be a bit careful when accessing the current context database, since it may not always be the database you think it is.

In this blog post I'll give an explanation on why the current context database may sometimes be the master database and other times may be the core database.

Where it all started to go wrong

It all started a couple of weeks back, when I was trying to grab an item from the Sitecore database, based on a specific template. When I called Sitecore.Context.Database.GetItem(...) with the specific template ID, I did not get anything back. Even more surprisingly, the Sitecore.Context.Database was pointing to the Core database and not the Master database like I would normally have expected.

So, what's going on here?

In order to come to the bottom of this, I decided to consult my colleague Brian Pedersen for help. Brian explained that this was normal behavior for Sitecore, if the context was 'Shell', whereas I would need to use Sitecore.Context.ContentDatabase to access the master database.

Following up on that question was then, how did the context change to 'Shell'? It turns out that if the URL is under /sitecore/ then Sitecore will automatically try to resolve the given context based on a algorithm that uses different parameters to decide the current context. The first match that fulfill the requirements wins the race, and is used as the context - and it turns out that 'Shell' is quite high on that list, meaning that if the URL contains /sitecore/shell/ then the context is Shell. In my case, I did not realize this at first, but I was actually trying to get the item from the database, while I was in the Content Editor, meaning that my URL contained /sitecore/shell, which is why the context was switched in the first place.

I didn't know this, but Sitecore actually comes with a set of default sites, each having a different configuration. You can head over to the official documentation on Sitecore Context and Databases, where everything is explained in details.

Now the database is right, but what about the context?

Using my newly acquired knowledge, I tried to grab the item I needed from the Master database using the Sitecore.Context.ContentDatabase, but it still returned a null value. Then I started thinking about the fact, that I was on a different context, i.e. the Shell context, and that the site I was normally working on would be in a different context.

Clarity animation image

At that point, things started to make a whole lot more meaning, since I would need to be in the right context, in order to fetch items from the site, as I would otherwise try to fetch items in the context of the Shell site, which naturally did not have my hand-created items.

So, in order to get my items I needed to be in the right context, meaning that I would need to switch from using the Shell context to my actual site context. In order to get it into the right context, it is possible to use one of the built-in switchers found inside the Sitecore API, called a SiteContextSwitcher. I've provided a small example that shows you, how this can be used:

Following along the lines are a few other switchers, which are explained more in detail in this blog post on how to correctly switching Sitecore contextes.

But, what about those multi-site solutions?

Imaging that you have a multi-site solution, let's say a site per language that the client uses. In that case, how does one determine which site to switch over to?

From what I've been able to figure out, the most clean way to go about this involves:

  • Getting the item being viewed
  • Getting all sites
  • Finding the first site for which the item falls within the tree path

Once the site has been located, you can then use the SiteContextSwitcher to switch over to the site and work against the correct context.