HttpResponse StatusCode - 在发送HTTP标头后,服务器无法设置状态

时间:2016-05-02 13:00:45

标签: c# asp.net sitecore

我尝试设置响应的StatusCode但每次出现异常时:服务器无法在发送HTTP标头后设置状态。我附上了部分代码,我尝试了各种解决方案来解决这个问题,但没有成功。谢谢你的帮助。

public class Custom404Page : Sitecore.Pipelines.HttpRequest.ExecuteRequest
{
    protected override void RedirectOnItemNotFound(string url)
    {
        try
        {
            SiteContext siteContext = Context.Site;
            Database database = Context.Database;
            RedirectTo404Page(siteContext, database);
        }
        catch (Exception ex)
        {
            LogManager.LogError(string.Format("Custom404Page throws exception. Redirection from {0} to custom 404 page failed.", url), ex);
        }
    }

    public void RedirectTo404Page(SiteContext siteContext, Database database)
    {
        try
        {
            if (String.IsNullOrEmpty(siteContext.StartPath))
            {
                return;
            }

            var startPage = database.GetItem(siteContext.StartPath);

            var paths = startPage.Paths;

            var parentPath = paths.ParentPath;

            var templateId = Page404Item.TemplateId;

            Item page404Item = database.SelectSingleItem("fast:/" + parentPath + "//*[@@templateid = '" + templateId + "']");

            if (page404Item != null)
            {
                if (page404Item.Versions.Count == 0)
                {
                    Language contentLanguage;
                    if (Language.TryParse(siteContext.Language, out contentLanguage))
                    {
                        Context.Language = contentLanguage;
                        page404Item = page404Item.Database.GetItem(page404Item.ID);
                    }
                }

                if (0 < page404Item.Versions.Count)
                {
                    string page404Url = GetUrlFromPage404Item(page404Item);
                    if (!string.IsNullOrEmpty(page404Url))
                    {
                        var context = HttpContext.Current;

                        context.Response.Clear();
                        context.Server.ClearError();

                        context.Response.BufferOutput = true;
                        context.Response.TrySkipIisCustomErrors = true;
                        context.Response.StatusCode = (int)HttpStatusCode.NotFound;

                        string html404Page = WebUtil.ExecuteWebPage(page404Url);
                        context.Response.Write(html404Page);

                        context.Response.Flush();
                        context.Response.SuppressContent = true;
                        context.ApplicationInstance.CompleteRequest();
                    }
                }
            }
        }
        catch (ThreadAbortException ex)
        {
        }
        catch (WebException ex)
        {
            LogManager.LogError(string.Format("Page404Provider throws WebException."), ex);
        }
        catch (Exception ex)
        {
            LogManager.LogError(string.Format("Page404Provider throws exception."), ex);
        }
    }

    private string GetUrlFromPage404Item(Item page404Item)
    {
        string url = string.Empty;

        Page404Item data = (Page404Item)page404Item;
        if (data.LinkTo404Page != null)
        {
            url = ItemUtility.CreateItemUrl(data.LinkTo404Page.Item, true);
        }

        return url;
    }
}

1 个答案:

答案 0 :(得分:0)

您只需在ItemResolver之后添加补丁即可处理无法找到的项目。

配置:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
    <sitecore>
        <settings>
            <!-- ID of the page that will be displayed when the requested url does not resolve to an actual page -->
            <setting name="Namespace.PageNotFound.ID" value="{017424DE-DB4F-4D9E-9AA1-5326527CC6A3}" />
        </settings>
        <pipelines>
            <httpRequestBegin>
                <processor type="Namespace.Global.Pipeline.Custom.Custom404Resolver, Namespace.Global" patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']" />
            </httpRequestBegin>
      <preprocessRequest help="Processors should derive from Sitecore.Pipelines.PreprocessRequest.PreprocessRequestProcessor">
        <processor type="Sitecore.Pipelines.PreprocessRequest.FilterUrlExtensions, Sitecore.Kernel">
          <param desc="Allowed extensions (comma separated)">*</param>
          <param desc="Blocked extensions (comma separated)">woff,eot,ttf,svg,gif,png,ico,jpg,jpeg,js,css</param>
          <param desc="Blocked extensions that stream files (comma separated)">*</param>
          <param desc="Blocked extensions that do not stream files (comma separated)"></param>
        </processor>
      </preprocessRequest>
    </pipelines>
    </sitecore>
</configuration>

处理器:

public class Custom404Resolver : HttpRequestProcessor
{
    public override void Process(HttpRequestArgs args)
    {
        Assert.ArgumentNotNull(args, "args");

        // Do nothing if the item is actually found
        if (Sitecore.Context.Item != null || Sitecore.Context.Database == null)
            return;

        // all the icons and media library items for the sitecore client need to be ignored
        if (args.Url.FilePath.StartsWith("/-/"))
            return;

        // Get the page not found item in Sitecore.

        var notFoundPagePath = Sitecore.IO.FileUtil.MakePath(Sitecore.Context.Site.StartPath, "Errors/page-not-found");
        var notFoundPage = Sitecore.Context.Database.GetItem(notFoundPagePath);

        if (notFoundPage == null)
        { 
            var notFoundPageId = Sitecore.Configuration.Settings.GetSetting("Namespace.PageNotFound.ID", "{017424DE-DB4F-4D9E-9AA1-5326527CC6A3}");
            notFoundPage = Sitecore.Context.Database.GetItem(notFoundPageId);
        }
        if (notFoundPage == null)
            return;

        // Switch to the 404 item
        Sitecore.Context.Item = notFoundPage;
    }
}

在sitecore的“404”页面上进行渲染的控制器:

public class ErrorController : BaseController
{
    public ActionResult PageNotFound()
    {
        Response.StatusDescription = "Page not found";
        Response.StatusCode = (int)HttpStatusCode.NotFound;
        Response.TrySkipIisCustomErrors = true;

        return Content(string.Empty);
    }
}

创建一个使用此操作的Controller Rendering,并将其放置在404发生时将显示的sitecore页面的演示文稿详细信息中。 此过程将保留网址,但会显示404网页内容,以及相应的404状态代码。