Customised error page

You can create error pages (404 - Page could not be found and 500 - Technical error) as pages in Sites. This allows you to choose your own error message on a page with the same look and feel as the rest of the site.

You need to implement two interfaces: IPageNotFoundResolver and IErrorHandler. Follow the steps below to customize your error 404 and 500 pages.

  1. Create an Error page type (you can use any name for the page type but Error is recommended).

    ErrorPageType
     
  2. Create two different templates for the page type, one for error 404 (page not found) and one for 500 (technical error).

    ErrorPageTypeTemplates
     
  3. Create two pages with the page type Error on your website, one using the template 404 and one using the template 500.

    Error page with template 404
    Put the following code in your template in order to return "Page not found (404)" status code.
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!CurrentState.IsInAdministrationMode)
      {
        Response.StatusCode = (int)HttpStatusCode.NotFound;
        Response.Status = "404 Not Found";
        Response.TrySkipIisCustomErrors = true;
      }
      RequestedUrl.Text = Server.HtmlEncode(Request.RawUrl);
    }
    
    ErrorPageWithTemplate404

    Error page with template 500
    Put the following code in your template in order to return "Internal server error (500)" status code.
     protected void Page_Init(object sender, EventArgs e)
    {
      if (CurrentState.IsInAdministrationMode) return;
      
      Response.StatusCode = (int)HttpStatusCode.InternalServerError;
      Response.Status = "500 Internal Server Error";
      Response.TrySkipIisCustomErrors = true;
    
      // Add random sleep due to Microsoft Security Advisory (2416728), obfuscate error time
      var delay = new byte[1];
      RandomNumberGenerator prng = new RNGCryptoServiceProvider();
      prng.GetBytes(delay);
      Thread.Sleep(delay[0]);
    }
    
    ErrorPageWithTemplate500
     
  4. In a class library project, implement the interfaces: IPageNotFoundResolver and IErrorPageResolver in your solution. 
    The implementation will try to find your page for the respective error and redirect the request to that page.
using Litium.Foundation.Modules.CMS;
using Litium.Foundation.Modules.CMS.Pages;
using Litium.Foundation.Modules.CMS.Plugins.Routing;
using Litium.Foundation.Modules.CMS.Routing;
using Litium.Foundation.Modules.CMS.WebSites;
using Litium.Foundation.Security;
using System.IO;
using System.Web;

namespace Litium.Studio.KC.Samples.CustomError
{
    public class CustomErrorResolver : IPageNotFoundResolver, IErrorPageResolver
    {
        /// <summary>
        /// Tries to the get the URL to the CMS page instance used for displaying page not found error message.
        /// </summary>
        ///<param name="pageRequestData"> The page request data.
        ///<param name="routePath"> The route path.
        /// <returns> <c>true</c> if page not found page is found; otherwise <c>false</c> . <paramref name="pageRequestData"> should contains the result of the page not found-page. </paramref></returns>
        public bool TryGetPageNotFound(PageRequestData pageRequestData, RoutePath routePath)
        {
            if (File.Exists(HttpContext.Current.Request.PhysicalPath))
                return false;

            var page = GetFirstPublishedPage("Error", "Error404",
                                        routePath.WebSite, ModuleCMS.Instance.AdminToken);

            if (page != null)
            {
                pageRequestData.PageID = page.ID;
                pageRequestData.SkipUrlCheck = true;
                return true;
            }

            return false;
        }

        /// <summary>
        /// Gets the first published page of the specified <see cref="PageType"> and <see cref="Template.Name"> published
        /// on the <see cref="WebSite"> as defined by the specified <see cref="RoutePath">.
        /// </see></see></see></see></summary>
        /// <returns>A <see cref="Page"> or null if no page was found.</see></returns>
        /// <remarks>Throws an exception if no <see cref="PageType"> can be found.</see></remarks>
        public Page GetFirstPublishedPage(string pageTypeName, string templateName, WebSite webSite, SecurityToken token)
        {
            var page = ModuleCMS.Instance.PageTypes[pageTypeName].Instances.GetPage(webSite,
                x => x.Template.Name.Equals(templateName) && x.IsPublished,
                token);

            return page;
        }

        public bool TryGetErrorPage(PageRequestData pageRequestData, RoutePath routePath)
        {
            if (File.Exists(HttpContext.Current.Request.PhysicalPath))
                return false;

            var page = GetFirstPublishedPage("Error", "Error500",
                                        routePath.WebSite, ModuleCMS.Instance.AdminToken);

            if (page != null)
            {
                pageRequestData.PageID = page.ID;
                pageRequestData.SkipUrlCheck = true;
                return true;
            }

            return false;
        }
    }
}
Is this page helpful?
Thank you for your feedback!