Sitecore keep or preserve url when 404 page not found

In some cases we don't want to redirect the users to a 404 page only because the users typed in the url wrongly. In this case what we want is to show the 404 content but keep or preserve the url. This way they can correct the url without having to type it in from scratch.

The way to do this in Sitecore is to execute some code before the OOTB RedirectOnItemNotFound code.

Create a config patch:

1
2
3
4
5
6
7
8
9
<sitecore>
  <pipelines>
    <httpRequestBegin>
  <!-- Overrides the default RedirectOnItemNotFound method to better handle 404 return codes. Run it before the standard Sitecore.Pipelines.HttpRequest.ExecuteRequest -->
  <processor patch:before="processor[@type='<namespace>.ExecuteRequest, Sitecore.Kernel']" type="<namespace>.ExecuteRequest, <assembly>"/>
  </processor>
    </httpRequestBegin>
  </pipelines>
</sitecore>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class ExecuteRequest : Sitecore.Pipelines.HttpRequest.ExecuteRequest
{
    protected override void RedirectOnItemNotFound(string url)
    {
        var context = HttpContext.Current;
 
        try
        {
            Log.Info(string.Format("Url: {0}", url), this);
 
            string content;
            using (var webClient = new WebClient())
            {
                webClient.Headers[HttpRequestHeader.UserAgent] = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
                content = webClient.DownloadString(string.Concat(domain, url));
            }
 
            // Send the NotFound page content to the client with a 404 status code
            context.Response.TrySkipIisCustomErrors = true;
            context.Response.StatusCode = 404;
            context.Response.Write(content);
        }
        catch (WebException ex)
        {
            WebResponse resp = ex.Response;
            using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
            {
                Log.Error(sr.ReadToEnd(), ex, this);
            }
            base.RedirectOnItemNotFound(url);
        }
        catch (Exception ex)
        {
            Log.Error(ex.Message, ex, this);
 
            // 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();
    }
}
And that's it.

HTH,
Andreas

Comments

Popular posts from this blog

SharePoint 2013 anonymous access add attachments to list item

CRM Plugin - Parent and Child Pipeline