C# 生产中的Sitecore自定义404处理程序

C# 生产中的Sitecore自定义404处理程序,c#,sitecore,C#,Sitecore,我从Stackoverflow->Sitecore中的一个重新处理自定义404的博客中获得了以下代码(该博客将302重定向到404页面,状态为200,被google作为soft 404获取) 虽然这在我们本地的测试服务器上运行得很好,但一旦我们将其投入生产,站点就会失控,需要8-9分钟的时间来加载和填充 public class ExecuteRequest : Sitecore.Pipelines.HttpRequest.ExecuteRequest { protected overr

我从Stackoverflow->Sitecore中的一个重新处理自定义404的博客中获得了以下代码(该博客将302重定向到404页面,状态为200,被google作为soft 404获取)

虽然这在我们本地的测试服务器上运行得很好,但一旦我们将其投入生产,站点就会失控,需要8-9分钟的时间来加载和填充

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

        try
        {
            // Request the NotFound page
            var domain = context.Request.Url.GetComponents(
                UriComponents.Scheme | UriComponents.Host, 
                UriFormat.Unescaped);

            var content = WebUtil.ExecuteWebPage(
                string.Concat(domain, url));

            // The line below is required for IIS 7.5 hosted 
            // sites or else IIS is gonna display default 404 page
            context.Response.TrySkipIisCustomErrors = true;
            context.Response.StatusCode = 404;
            context.Response.Write(content);
        }
        catch (Exception ex)
        {
            Log.Error(string.Format("Falling back to default redirection behavior. Reason for error {0}", ex), ex);

            // Fall back to default behavior on exceptions
            base.RedirectOnItemNotFound(url);
        }

        context.Response.End();
    }
} 
附言:然后我在web.config中将ExecuteRequest替换为我的自定义任务

如果你经历过类似的事情或知道任何问题,请一定要说明


提前感谢

Sitecore中有一个设置,您可以通过该设置摆脱302重定向:

<setting name="RequestErrors.UseServerSideRedirect" value="true" />

通过此设置,url保持不变,状态代码为404。如果您想拥有一些额外的逻辑(如将Sitecore项目显示为错误页面),则在上有一个名为error Manager的共享源模块


希望有帮助。

检查服务器是否能够访问您网站的主机名

服务器通常无法访问DNS,因此无法解析主机名。为了让404处理程序工作,应用程序需要能够访问自己的主机名以请求404页面


要确保这一点,请编辑服务器的文件并在其中添加主机名条目,将其指向127.0.0.1

您可以通过创建新的解析程序来解析它。当您想用正确的语言向用户提供错误页面时,这是一个很好的解决方案。但是iis7.0和7.5有一些不同之处

将处理器添加到sitecore配置:

<processor type="Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel"/>
<processor type="Project.Error404Resolver, Project" />
对于IIS 7.5:

public class Error404Resolver : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
{
    public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        if(Sitecore.Context.Item == null && !args.Context.Request.Url.AbsolutePath.StartsWith("/sitecore")
        {
            args.Context.Response.Clear();

            SiteContext site = Sitecore.Context.Site;
            if(site != null)
            {
                Item item404Page = Sitecore.Context.Database.GetItem(site.RootPath + "website/error/404");
                if(item404Page != null)
                {
                    Sitecore.Context.Item = item404Page;
                    args.Context.Response.StatusCode = (int) System.Net.HttpStatusCode.NotFound;
                }
            }
        }
    }
}
public class Error404Resolver : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
{
    public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
    {
        if(Sitecore.Context.Item == null && !args.Context.Request.Url.AbsolutePath.StartsWith("/sitecore")
        {
            args.Context.Response.Clear();

            SiteContext site = Sitecore.Context.Site;
            if(site != null)
            {
                Item item404Page = Sitecore.Context.Database.GetItem(site.RootPath + "website/error/404");
                if(item404Page != null)
                {
                    WebClient webClient = new WebClient();
                    webClient.Encoding = args.Context.Request.ContentEncoding;
                    webClient.Headers.Add("User-Agent", args.Context.Request.UserAgent);
                    string page = webClient.DownloadString(LinkManager.GetItemUrl(item404Page));

                    args.Context.Response.StatusCode = (int) System.Net.HttpStatusCode.NotFound;
                    args.Context.Response.Write(page);
                    args.Context.Response.TrySkipIisCustomErrors = true;
                    args.Context.Response.End();
                }
            }
        }
    }
}

这样,您将在当前页面中呈现错误页面,而不重定向,并返回到浏览器代码404。

我当前工作的客户也有同样的问题(看起来代码是粘贴的),实际上原因很明显:如果您使用未在Sitecore sites config中注册的url执行此调用(但可通过IIS访问),您还将运行此代码。不幸的是,WebUtil.ExecuteWebPage调用也是使用错误的url执行的,因此您最终陷入了循环中

实际上,您应该在日志中看到很多这样的消息:返回默认重定向行为。错误{0}的原因可能是超时


如果您真的想使用自定义处理程序,在调用WebUtil.ExecuteWebPage之前,应该检查您是否处于正确的站点上下文中。

只要404页面是文件,而不是Sitecore项目,此操作就有效。Sitecore错误管理器使用一个文件处理404,该文件呈现Sitecore项目。通过这种方式,您可以将项目作为404页面并使用上面提到的设置来摆脱302。我原以为对WebUtil.ExecuteWebPage的调用在任何其他流量较小的情况下都会有问题。太多的回送web请求会触发。如果您的404页面以某种方式调用404本身,您可能会进入循环(可能就是这样发生的吧?)