Sitecore 通过 processor 来自定义类似 github 的 not found 页面

有一个需求是类似 github 的 404 页面,当访问不存在的页面时,需要满足以下几点:

  1. 不是通过redirect或其他状态码让浏览器来跳转到到404页面;
  2. 链接还是原来链接,但是页面内容是 404;
  3. 由于是MVC模式,功能由 back-end 来实现;
  4. 状态码得是 404。

image

在基于 sitecore 的框架上,使用 sitecore 的 processor 来实现此功能:
文档地址:https://doc.sitecore.com/xp/en/developers/latest/sitecore-experience-manager/mvc-and-pipelines.html#mvc-specific-processors

using System.Net;
using System.Web;
using Sitecore.Diagnostics;
using Sitecore.Layouts;
using Sitecore.Pipelines.HttpRequest;
using Sitecore.Web;

namespace SitecoreConsole
{
    public class NotFoundProcessor : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
    {
        public string ItemNotFoundItemPath { get; set; }
        public string MapContentItemPath { get; set; }

        public override void Process(HttpRequestArgs args)
        {
            string siteStartPath = Sitecore.Context.Site.StartPath;
            PageContext page = Sitecore.Context.Page;
            string filePath = page?.FilePath;

            if (Sitecore.Context.Item != null || Sitecore.Context.Site == null || Sitecore.Context.Database == null)
            {
                return;
            }

            if (Sitecore.Context.Item == null)
            {
                string fullUrl = WebUtil.GetFullUrl(WebUtil.GetRawUrl());
                string cacheKey = $"cacheKey_{fullUrl}";
                
                string isActiveCache = string.Empty;
                if (Sitecore.Context.Site.CacheHtml && (isActiveCache = Sitecore.Context.Site.Caches.HtmlCache.GetHtml(cacheKey)) == "active")
                {
                    return;
                }

                // 这个是处理一个 AutoLinkMap,将一个链接映射到另一个链接的程序,此处可以是不到此功能
                // if (string.IsNullOrEmpty(isActiveCache))
                // {
                //     var mapContentItem = Sitecore.Context.Database.GetItem(string.Concat(siteStartPath, MapContentItemPath));
                //     if (mapContentItem != null)
                //     {
                //         if (!string.IsNullOrEmpty(mapContentItem.Fields["XML Mapping"]?.Value))
                //         {
                //             string mapContent = mapContentItem.Fields["XML Mapping"].Value;
                //             if (mapContent.IndexOf($"<oldlink>{fullUrl}</oldlink>", StringComparison.OrdinalIgnoreCase) != -1)
                //             {
                //                 if (Sitecore.Context.Site.CacheHtml)
                //                 {
                //                     Sitecore.Context.Site.Caches.HtmlCache.SetHtml(cacheKey, "active");
                //                 }
                //
                //                 return;
                //             }
                //         }
                //     }
                //
                //     if (Sitecore.Context.Site.CacheHtml)
                //     {
                //         Sitecore.Context.Site.Caches.HtmlCache.SetHtml(cacheKey, "disabled");
                //     }
                // }

                var notFoundItem = Sitecore.Context.Database.GetItem(string.Concat(siteStartPath, ItemNotFoundItemPath));
                if (notFoundItem != null)
                {
                    HttpContextBase httpContext = args.HttpContext;
                    if (httpContext != null)
                    {
                        httpContext.Items["PageNotFound"] = 1;
                    }

                    Sitecore.Context.Item = notFoundItem;
                    Log.Debug("[NotFoundProcessor] Set to item " + notFoundItem.Paths.FullPath, this);
                }
                else
                {
                    Log.Debug("[NotFoundProcessor] notFoundItem not found", this);
                }
            }
        }
    }
    
    public class SetHttpResponseCode : HttpRequestProcessor
    {
        public override void Process(HttpRequestArgs args)
        {
            HttpContextBase httpContext = args.HttpContext;
            if (httpContext != null)
            {
                if (Sitecore.MainUtil.GetBool(httpContext.Items["PageNotFound"], false))
                {
                    HttpContext.Current.Response.TrySkipIisCustomErrors = true;
                    HttpContext.Current.Response.StatusCode = (int)HttpStatusCode.NotFound;
                }
            }
        }
    }
}

配置文件

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
    <sitecore role:require="ContentDelivery">
        <pipelines>
            <httpRequestBegin>
                <processor type="SitecoreConsole.NotFoundProcessor, SitecoreConsole"
                           patch:before="processor[@type='Sitecore.Pipelines.HttpRequest.LayoutResolver, Sitecore.Kernel']">
                    <ItemNotFoundItemPath>/404</ItemNotFoundItemPath>
                    <!--<LinkMapContentItemPath>/Map Content</LinkMapContentItemPath>-->
                </processor>
            </httpRequestBegin>
            <httpRequestEnd>
                <processor type="SitecoreConsole.SetHttpResponseCode, SitecoreConsole"
                           patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.EndDiagnostics, Sitecore.Kernel']" />
            </httpRequestEnd>
        </pipelines>
    </sitecore>
</configuration>
posted @ 2024-09-02 15:03  灵火  阅读(51)  评论(0)    收藏  举报