Incorrect behavior in Sitecore when custom item set into Context.Item?

Life at Apollo Division
Life at Apollo Division
2 min readJul 21, 2020
Photo by Chris Ried on Unsplash

Consider the following scenario:

  • You are using MVC
  • You have a /content/page1 item
  • There is some specific requirement, that for specific users, request on this URL should end with custom 404 error page
  • You will implement custom 404 handlers in the httpRequestBegin pipeline following way

1. this.sitecoreContext.Item = error404Item;

2. this.sitecoreContext.Items[“httpStatus”] = httpStatusCode.NotFound;

3. args.HttpContext.Response.TrySkipIisCustomErrors = true;

  • You test it for some non-existing page (/content/some-page-does-not-exists) and everything works correctly (404 page is displayed)
  • You try to access /content/page1 and …. regardless that in httpRequestBegin processor you injected your 404 page into the Sitecore.Context, original /content/page1 appears

For any reason, if you are using MVC, Sitecore again reevaluates the context item and tries to again translate URL into the item, regardless of what is in existing Sitecore.Context.Item.

In 95% cases, this behavior is OK, because you typically use this scenario when the requested item really does not exists (in this scenario, Sitecore.Context.Item is not touched). But if you are using some “strange customizations” and you are sometimes serving 404 pages also for the existing items, this causes that URL is again reevaluated, and reference to the 404 item is replaced by originally requested item.

This logic happens in the mvc.GetPageItem pipeline, in Sitecore.Mvc.Pipelines.Response.GetPageItem.GetFromRouteUrl processor. And there is a very easy way to change this behavior to the expected state.

You need to do 2 steps:

  • In the 404 handler, you need to set some flag, which will be request-related and will inform our other processor, that we set our 404 item
  • Create own handler for the GetPageItem processor, and when our flag arrives, adjust pipeline parameters

Our 404 handler in httpRequestBegin will look very similar to the original:

1. this.sitecoreContext.Item = error404Item;

2. this.sitecoreContext.Items[“httpStatus”] = HttpStatusCode.NotFound;

3. this.sitecoreContext.Items[“404_processed”] = true;

4. args.HttpContext.Response.TrySkipIisCustomErrors = true;

And our GetPageItem will look like this:

1. if (this.sitecoreContext.Items.Contains(“404_processed”))

2. {

3. args.Result = this.sitecoreContext.Item;

4. }

And that’s all.

We are ACTUM Digital and this piece was written by Tomas Knaifl, Senior .NET Developer of Apollo Division. Feel free to get in touch.

--

--