Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom 404 page in sitecore from content tree

I have multilingual website and I want a custom 404 page in all languages which depends on the context of the site. What is the correct approach to get the 404 page defined in content tree or to access 404 page from content tree? I am able to get 404 page if I will define that in my site root but not from content tree.

enter image description here

I want 404page from the content tree as my 404 Custom redirect.

My Webconfig setting:

<setting name="ItemNotFoundUrl" value="/404Page.aspx" />

IIS 404 entry. enter image description here

The error i got when page is not there in sitecore:

After changing IIS to default and setting httpErrors like

  <error statusCode="404" path="/404PAGE.aspx" responseMode="ExecuteURL" />

</httpErrors>

enter image description here

like image 921
Sam Avatar asked Dec 01 '22 17:12

Sam


1 Answers

I use a custom implementation of the ExecuteRequest processor in the httpBeginRequest pipeline.
That is where the 404 requests are eventually handled.

You can override the RedirectOnItemNotFound method in there and add some logic to load a different 404 page per site.

Take a look at this blog post that explains how to implement it.

EDIT: I have added an example of how to implement it so you can return a site specific 404 page.

If you make this modification, you can return a different 404 page per site:

Add this to the configuration:

<setting name="NotFoundPage.SiteName1" value="/not-found.aspx" />
<setting name="NotFoundPage.SiteName2" value="/not-found.aspx" />

Then in the custom RedirectOnItemNotFound code, do this to return site specific 404 content:

public class ExecuteRequest : Sitecore.Pipelines.HttpRequest.ExecuteRequest
{
    protected override void RedirectOnItemNotFound(string url)
    {
        var context = System.Web.HttpContext.Current;

        try
        {
            // Get the domain of the current request.
            string domain = context.Request.Url.GetComponents(UriComponents.Scheme | UriComponents.Host, UriFormat.Unescaped);

            // Get 'not found page' setting for current site.
            string notFoundUrl = Sitecore.Configuration.Settings.GetSetting(string.Conact("NotFoundPage.", Sitecore.Context.Site.Name));

            // Request the contents of the 'not found' page using a web request.
            string content = Sitecore.Web.WebUtil.ExecuteWebPage(string.Concat(domain, notFoundUrl));

            // Send the content to the client with a 404 status code
            context.Response.TrySkipIisCustomErrors = true;
            context.Response.StatusCode = 404;
            context.Response.Write(content);
        }
        catch (Exception)
        {
            // If our plan fails for any reason, fall back to the base method
            base.RedirectOnItemNotFound(url);
        }

        // Must be outside the try/catch, cause Response.End() throws an exception
        context.Response.End();
    }
}

The idea is that you use the site name as setting key so you can resolve the configuration value per site.
The code needs some work of course, but you get the idea..

EDIT 2: Added example configuration to replace the original pipeline processor with the new one:

<pipelines>
  <httpRequestBegin>
    <processor type="Sitecore.Pipelines.HttpRequest.ExecuteRequest, Sitecore.Kernel">
      <patch:attribute name="type">ParTech.Pipelines.ExecuteRequest, ParTech</patch:attribute>
    </processor>
  </httpRequestBegin>
</pipelines>
like image 200
Ruud van Falier Avatar answered Dec 18 '22 22:12

Ruud van Falier