Skip to content

Instantly share code, notes, and snippets.

@janhebnes
Created October 27, 2012 02:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save janhebnes/3962756 to your computer and use it in GitHub Desktop.
Save janhebnes/3962756 to your computer and use it in GitHub Desktop.
Sitecore CMS - PageNotFound 404 handling using a Sitecore Item as ErrorPage
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Diagnostics;
using Sitecore.Layouts;
using Sitecore.Pipelines.HttpRequest;
using Sitecore.Sites;
using Sitecore.Web;
namespace SitecoreExtensions.Pipelines.HttpRequest
{
/// <summary>
/// Instead of overridding the last pipeline element and returning a html error page
/// We override just after the ItemResolver and return the error page if the item is empty, allowing the layoutResolver to run on the error Item.
/// The error handling is copied from the Sitecore.Pipelines.HttpRequest.ExecuteRequest
/// </summary>
/// <remarks>
/// Installation:
/// Add to HttpRequestBegin after Sitecore.Pipelines.HttpRequest.ItemResolver and before Sitecore.Pipelines.HttpRequest.LayoutResolver
/// and add httpErrors existingResponse="PassThrough" to system.webServer for allowing the 404 header to be returned by the page
/// </remarks>
/// <example>
/// Rendering to be added to the 404 page for returning correct status code
///
/// public partial class PageNotFoundResponseHeader : System.Web.UI.UserControl
/// {
/// protected void Page_Load(object sender, EventArgs e)
/// {
/// Log.Error("Request 404 Page not found - " + Sitecore.Context.RawUrl, typeof(PageNotFoundResponseHeader));
/// Response.TrySkipIisCustomErrors = true;
/// Response.StatusCode = 404;
/// Response.StatusDescription = "Page not found";
/// }
/// }
/// </example>
public class ItemNotFoundResolver : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
{
/// <summary>
/// Pipeline processor implementation.
/// </summary>
/// <param name="args">Pipeline processor arguments.</param>
public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (Sitecore.Context.Item != null)
{
// Fall through to default handler
return;
}
SiteContext site = Context.Site;
if (((site != null) && !SiteManager.CanEnter(site.Name, Context.User)))
{
// Fall through to default handler
return;
}
PageContext page = Context.Page;
Assert.IsNotNull(page, "No page context in processor.");
string filePath = page.FilePath;
if (filePath.Length > 0)
{
if (WebUtil.IsExternalUrl(filePath))
{
args.Context.Response.Redirect(filePath, true);
}
else
{
args.Context.RewritePath(filePath, args.Context.Request.PathInfo, args.Url.QueryString, false);
}
}
else if (Context.Item == null)
{
this.HandleItemNotFound(args);
}
}
private void HandleItemNotFound(HttpRequestArgs args)
{
string localPath = args.LocalPath;
string name = Context.User.Name;
bool flag = false;
string itemNotFoundUrl = Settings.ItemNotFoundUrl;
if (args.PermissionDenied)
{
flag = true;
// Fall through to default handler
return;
////itemNotFoundUrl = this.GetNoAccessUrl(out loginPage);
}
SiteContext site = Context.Site;
string str4 = (site != null) ? site.Name : string.Empty;
List<string> list = new List<string>(new string[] { "item", localPath, "user", name, "site", str4 });
if (Settings.Authentication.SaveRawUrl)
{
list.AddRange(new string[] { "url", HttpUtility.UrlEncode(Context.RawUrl) });
}
itemNotFoundUrl = WebUtil.AddQueryString(itemNotFoundUrl, list.ToArray());
if (!flag)
{
if (Context.Database == null)
{
// Fall through to default handler
return;
}
// Find context site root
var root = args.GetItem(Context.Site.StartPath);
if (root == null)
{
// Fall through to default handler
return;
}
// Find context site pagenotfound pages // Must be located straight under the root
IEnumerable<PageNotFoundPageItem> pageNotFoundItems = root.GetChildren<PageNotFoundPageItem>();
foreach (PageNotFoundPageItem item in pageNotFoundItems)
{
if ((item != null) && (item.InnerItem.Versions.Count > 0))
{
Context.Item = item;
break;
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment