2016-05-02 16 views
0

ResponseのStatusCodeを設定しようとしましたが、例外が発生するたびにサーバーはHTTPヘッダーが送信された後でステータスを設定できません。コードの一部を添付しましたが、これを修正するためにさまざまな解決策を試しましたが、成功しませんでした。ご協力ありがとうございました。HttpResponse 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; 
    } 
} 
+0

'Response.Write()'を使う前に 'StatusCode'を設定するとどうなりますか? – NineBerry

+0

同じ問題です。それは助けにならない。 – Krpo

+0

最初に 'context.Response.Clear();'をやってみましたか? –

答えて

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; 
    } 
} 

コントローラーサイトコアの "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); 
    } 
} 

このアクションを使用してコントローラのレンダリングを作成します。 404が発生したときに表示されるサイトのページのプレゼンテーションの詳細に配置します。 このプロセスではURLは保存されますが、代わりに適切な404ステータスコードとともに404ページのコンテンツが表示されます。

+0

RedirectPermanentメソッドを使用する良い解決策になりますか?私はそれが動作すると思った多くの解決策の1つとして、StatusCodeだけを404に設定します。私の解決策の1つとして、404項目にContext.Itemを直接設定しようとしましたが、うまく機能しませんでした。私はウェブフォームで作業しています。 – Krpo

+0

コントローラーレンダリングは、サブレイアウトを通じてWebformsユーザーコントロールとして行うこともできます。 RedirectPermanentは、要求されたURLが別のURLによって提供されている場合に適切な、ステータスコード301(Permanent Moved)を設定します。あなたの質問は、404コードが必要な、見つからないアイテムに関するものでした。 404コンテンツを提供するページにコンテキストアイテムを割り当てることは、私がずっとやっているように実際に機能します。おそらくhttpRequestBeginパイプラインに他のパッチがありますか? http://stackoverflow.com/questions/17517318/redirect-vs-redirectpermanent-in-asp-net-mvc –

+0

ありがとうございました。したがって、私が必要とする上記の説明は、あなたのErrorControllerからサブレイアウトとコードを使ってユーザーコントロールを作成し、コントロールとしてプレゼンテーションの詳細でカスタム404ページに割り当てることです。私はこのページ(ヘッダー、フッターなど)の4つのコントロールを定義しました。今のところソリューションとして、私はServer.TransferRequestメソッドを使用することを選択します。まず、私の問題はLayoutResolverに関するもので、これに対してレイアウトが定義されていないアイテムを処理しています。アイテムが存在するがレイアウトは割り当てられていないため、Server.TransferRequest()を使用できると思います。そして、存在しないアイテムのコードをチェックします。 – Krpo

関連する問題