内容树中sitecore中的自定义404页面

内容树中sitecore中的自定义404页面,sitecore,multilingual,Sitecore,Multilingual,我有多语言的网站,我想在所有语言,这取决于网站的上下文自定义404页。获取内容树中定义的404页面或从内容树访问404页面的正确方法是什么?我能够得到404页,如果我将在我的网站根定义,但不是从内容树 我想从内容树404页作为我的404自定义重定向 我的网络配置设置: <setting name="ItemNotFoundUrl" value="/404Page.aspx" /> IIS 404条目。 页面不在sitecore中时出现的错误: 将IIS更改为默认值并将htt

我有多语言的网站,我想在所有语言,这取决于网站的上下文自定义404页。获取内容树中定义的404页面或从内容树访问404页面的正确方法是什么?我能够得到404页,如果我将在我的网站根定义,但不是从内容树

我想从内容树404页作为我的404自定义重定向

我的网络配置设置:

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

IIS 404条目。

页面不在sitecore中时出现的错误:

将IIS更改为默认值并将httpErrors设置为
  <error statusCode="404" path="/404PAGE.aspx" responseMode="ExecuteURL" />

</httpErrors>


Sitecore自己做了一些“未找到项”处理,也没有以SEO友好的方式很好地处理404

我找到的处理Sitecore中404和其他错误的最佳解决方案是Sitecore错误管理器


您可以在Sitecore配置中将
ItemNotFoundUrl
设置为内容树中的任何项目,它不需要位于站点根目录中,只要您不指定语言,它将使用用户浏览站点时使用的任何语言(或首次访问时的默认语言)。对于所有站点,项目必须位于相同的树结构中,但:

<setting name="ItemNotFoundUrl" value="/errors/404.aspx" />
<setting name="LayoutNotFoundUrl" value="/errors/500.aspx"/>
<setting name="NoAccessUrl" value="/errors/403.aspx"/>
这将触发
ExecuteRequest
管道中的以下代码

protected virtual void PerformRedirect(string url)
{
  if (Settings.RequestErrors.UseServerSideRedirect)
    HttpContext.Current.Server.Transfer(url);
  else
    WebUtil.Redirect(url, false);
}
你可以在这篇文章中了解更多。确保在处理当前System.Web.HttpResponse的代码中将其Status属性设置为404。文档中有更多信息


不过,错误管理器是一个很棒的模块,如果您需要为不同的站点设置不同的url位置,它会更加灵活。

我在
httpBeginRequest
管道中使用
ExecuteRequest
处理器的自定义实现。
这就是404请求最终被处理的地方

您可以覆盖其中的
redirectonimnotfound
方法,并添加一些逻辑来为每个站点加载不同的404页面

看一看,它解释了如何实现它

编辑:我添加了一个如何实现它的示例,以便您可以返回特定于站点的404页面。

如果进行此修改,则每个站点可以返回不同的404页面:

将此添加到配置中:

<setting name="NotFoundPage.SiteName1" value="/not-found.aspx" />
<setting name="NotFoundPage.SiteName2" value="/not-found.aspx" />
其思想是使用站点名称作为设置键,以便可以解析每个站点的配置值。
代码当然需要做一些工作,但你已经明白了

编辑2:添加示例配置,用新的管道处理器替换原来的管道处理器:

<pipelines>
  <httpRequestBegin>
    <processor type="Sitecore.Pipelines.HttpRequest.ExecuteRequest, Sitecore.Kernel">
      <patch:attribute name="type">ParTech.Pipelines.ExecuteRequest, ParTech</patch:attribute>
    </processor>
  </httpRequestBegin>
</pipelines>

ParTech.Pipelines.ExecuteRequest,ParTech

我已经就此写了一篇博文,可能对将来的人有用

我采取的方法是:

  • HttpRequestBegin
    管道上的
    HttpRequest.itemsolver
    之后添加处理器
  • 查找上下文项是否为null,如果为null,则将404内容页设置为上下文项
  • EndDiagnostics
    处理器之后的管道
    httpRequestEnd
    中添加另一个处理器,以设置未找到项目的404状态代码
使用这种方法,我们不需要在渲染上设置404状态代码。我们将其设置在“httpRequestEnd”管道的末尾/404页返回200状态代码,因为此页假定返回200状态代码


在多站点/多语言环境中工作

这对我不起作用。这是我所做的。@Sam用额外的信息更新您的原始问题,如果您保留IIS默认值,只需更改web.config(sitecore+
)中的设置,会发生什么情况?您能直接在浏览器中浏览到404页吗?确保项目已发布(并在工作流中批准,如果您启用了项目),是项目已发布,我可以直接浏览页面或预览页面。Ruud,我们是否必须将两个处理器都保持在webconfig中,如果是,则按哪个顺序进行。在使用上述代码后,我也遇到了异常。忘了提及这一点。您应该用新的处理器替换现有的处理器。我已经添加了一个如何做到这一点的示例。你得到了什么例外?Ruud,我可以修复验证问题,但page在多语言场景中无法工作。就像我在法语网站(www.abc.com/fr/sjdfsl)上一样,该页面没有出现错误页面的法语版本。有什么意见吗
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();
    }
}
<pipelines>
  <httpRequestBegin>
    <processor type="Sitecore.Pipelines.HttpRequest.ExecuteRequest, Sitecore.Kernel">
      <patch:attribute name="type">ParTech.Pipelines.ExecuteRequest, ParTech</patch:attribute>
    </processor>
  </httpRequestBegin>
</pipelines>