82

Googleウェブマスターツール用にサイトをセットアップしようとしたところ、カスタムASP.NET404ページが404ステータスコードを返さないことがわかりました。正しいカスタムページが表示され、すべてがOKであることがブラウザに通知されました。これはソフト404または偽404と見なされます。Googleはこれを好みません。そのため、この問題に関する多くの記事を見つけましたが、私が望む解決策はうまくいかなかったようです。

私が働きたい解決策は、カスタム404ページのPage_Loadメソッドの背後にあるコードに次の2行を追加することです。

Response.Status = "404 Not Found";
Response.StatusCode = 404;

これは機能しません。ページはまだ200OKを返します。ただし、次のコードをデザインコードにハードコーディングすると、正しく機能することがわかりました。

<asp:Content ID="ContentMain" ContentPlaceHolderID="ContentPlaceHolderMaster" runat="server">

<%
    Response.Status = "404 Not Found";
    Response.StatusCode = 404;
%>

 ... Much more code ...

</asp:content>

ページはマスターページを使用しています。そして、web.configでカスタムエラーページを構成しています。私は実際にはコードビハインドオプションを使用したいのですが、デザイン/レイアウトにハックインラインコードを配置せずにそれを機能させることはできないようです。

4

7 に答える 7

73

解決:

問題は、マスターページの使用でした。ページのライフサイクルの後半でステータスコードを設定することで機能するようになりました。明らかにマスターページのレンダリングでリセットされていたため、renderメソッドを上書きして、レンダリングの完了後に設定しました。

protected override void Render(HtmlTextWriter writer)
{
    base.Render(writer);
    Response.StatusCode = 404;
}

マスターページがいつステータスを設定しているかを正確に把握するために、さらに多くの作業を行うことができますが、それはあなたに任せます。


元の投稿:

テストWebアプリを正常に動作させることができました。少なくとも、カスタムエラーページが表示され、404ステータスコードが返されました。アプリの何が問題になっているのかはわかりませんが、私が何をしたのかはわかります。

1)カスタムエラーのweb.configを編集しました:

<customErrors mode="On">
  <error statusCode="404" redirect="404.aspx"/>
</customErrors>

2)404.aspxページを追加し、ステータスコードを404に設定します。

public partial class _04 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.StatusCode = 404;
    }
}

それについてです。Asp.Netによって処理され、存在しないページ拡張に移動すると、フィドラーログに404が明確に表示されます。ヘッダーは次のとおりです。

HTTP/1.1 404 Not Found
Server: Microsoft-IIS/5.1
Date: Sun, 07 Dec 2008 06:04:13 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 533

ここで、htmファイルのようにAsp.Netで処理されていないページに移動すると、カスタムページが表示されず、IISによって構成されている404が表示されます。

これはあなたとあなたの問題に役立つかもしれないいくつかの詳細に入る投稿です、私のテストは新しいページへのリダイレクトを行うので、要求されたファイルのURLはほとんど失われます(クエリ文字列内のものを除く) 。

Google404および.NETカスタムエラーページ

ヘッダースパイ応答:

HTTP/1.1 404 Not Found
Date: Sun, 07 Dec 2008 06:21:20 GMT
于 2008-12-07T06:13:07.753 に答える
29

カスタム ページを 404 (ASPX) として表示したいという同様の問題があり、localhost では問題なく動作しましたが、リモートの訪問者が接続するとすぐに、一般的な IIS 404 が表示されます。

これに対する解決策は、追加することでした

Response.TrySkipIisCustomErrors = true;

Response.StatusCode を変更する前。

Rick Strahl 経由で見つけたhttp://www.west-wind.com/weblog/posts/745738.aspx

于 2010-06-22T23:28:31.643 に答える
12

IIS 7 のソリューションは、これを web.config ファイルに追加するだけです。

<system.webServer>
  <httpErrors existingResponse="Replace">
    <remove statusCode="500" subStatusCode="-1" />
    <remove statusCode="404" subStatusCode="-1" />
    <error statusCode="404" prefixLanguageFilePath="" path="404.htm" responseMode="File" />
    <error statusCode="500" prefixLanguageFilePath="" path="500.htm" responseMode="File" />
  </httpErrors>
</system.webServer>

http://forums.asp.net/t/1563128.aspx/1

于 2012-04-03T08:05:06.000 に答える
12

Response.End() を呼び出して、レンダリングをスキップしてみてください...

Response.Status = "404 Not Found";
Response.StatusCode = 404;
Response.End();
return;
于 2010-09-22T00:06:05.943 に答える
9

多くのテストとトラブルシューティングを行った結果、特定のホスティング プロバイダーがリターン コードに干渉する可能性があることがわかりました。コンテンツに「ハック」を適用することで、これを回避できました。

<%
// This code is required for host that do special 404 handling...
Response.Status = "404 Not Found";
Response.StatusCode = 404;
%>

これにより、ページは何があっても正しいリターン コードを返すことができます。

于 2008-12-08T01:54:36.883 に答える
1

.NET 3.5.

私が実装したパターンは、web.config で .NET のカスタム リダイレクト ソリューションをバイパスします。これは、ヘッダーに正しい HTTP ステータス コードを含むすべてのシナリオを処理する独自のパターンを作成したためです。

まず、web.config の customErrors セクションは次のようになります。

<customErrors mode="RemoteOnly" defaultRedirect="~/error.htm" />

この設定により、CustomErrors モードが確実に on に設定されます。この設定は後で必要になります。また、error.htm の defaultRedirect に all-else-fails オプションを提供します。これは、特定のエラーのハンドラーがない場合や、データベース接続が壊れているような場合に役立ちます。

次に、グローバル asax エラー イベントを次に示します。

protected void Application_Error(object sender, EventArgs e)
    {
       HandleError();
    }

    private void HandleError()
    {
        var exception = Server.GetLastError();
        if (exception == null) return;

        var baseException = exception.GetBaseException();

        bool errorHandled = _applicationErrorHandler.HandleError(baseException);
        if (!errorHandled) return;


        var lastError = Server.GetLastError();
    if (null != lastError && HttpContext.Current.IsCustomErrorEnabled)
    {
        Elmah.ErrorSignal.FromCurrentContext().Raise(lastError.GetBaseException());
        Server.ClearError();
    }
    }

このコードは、エラーを処理する責任を別のクラスに渡しています。エラーが処理されず、CustomErrors がオンになっている場合、それは、本番環境にあり、エラーが処理されていないというケースがあることを意味します。ユーザーに見えないようにここでクリアしますが、Elmah にログを記録して、何が起こっているかを把握します。

applicationErrorHandler クラスは次のようになります。

public bool HandleError(Exception exception)
        {
            if (exception == null) return false;

            var baseException = exception.GetBaseException();

            Elmah.ErrorSignal.FromCurrentContext().Raise(baseException);

            if (!HttpContext.Current.IsCustomErrorEnabled) return false;

            try
            {

                var behavior = _responseBehaviorFactory.GetBehavior(exception);
                if (behavior != null)
                {
                    behavior.ExecuteRedirect();
                    return true;
                }
            }
            catch (Exception ex)
            {
                Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
            }
            return false;
        }

このクラスは基本的にコマンド パターンを使用して、発行されたエラーの種類に適したエラー ハンドラーを見つけます。ほとんどすべてのエラーが上位レベルの例外にラップされるため、このレベルで Exception.GetBaseException() を使用することが重要です。たとえば、任意の aspx ページから "throw new System.Exception()" を実行すると、System.Exception ではなく、このレベルで HttpUnhandledException が受信されます。

「ファクトリー」コードは単純で、次のようになります。

public ResponseBehaviorFactory()
    {
        _behaviors = new Dictionary<Type, Func<IResponseBehavior>>
                        {
                            {typeof(StoreException), () => new Found302StoreResponseBehavior()},
                            {typeof(HttpUnhandledException), () => new HttpExceptionResponseBehavior()},
                            {typeof(HttpException), () => new HttpExceptionResponseBehavior()},
                            {typeof(Exception), () => new Found302DefaultResponseBehavior()}
                        };
    }

    public IResponseBehavior GetBehavior(Exception exception)
    {                                                                               
        if (exception == null) throw new ArgumentNullException("exception");

        Func<IResponseBehavior> behavior;
        bool tryGetValue = _behaviors.TryGetValue(exception.GetType(), out behavior);

        //default value here:
        if (!tryGetValue)
            _behaviors.TryGetValue(typeof(Exception), out behavior);

        if (behavior == null)
            Elmah.ErrorSignal.FromCurrentContext().Raise(
                new Exception(
                    "Danger! No Behavior defined for this Exception, therefore the user might have received a yellow screen of death!",
                    exception));
        return behavior();
    }

最後に、拡張可能なエラー処理スキームのセットアップを取得しました。定義されている「動作」のそれぞれに、エラーのタイプのカスタム実装があります。たとえば、HTTP 例外はステータス コードを検査され、適切に処理されます。404 ステータス コードには、Request.Redirect の代わりに Server.Transfer が必要であり、ヘッダーに適切なステータス コードが書き込まれています。

お役に立てれば。

于 2012-04-20T17:32:55.207 に答える
0

以下のコードを使用できます。

 Response.TrySkipIisCustomErrors = True
 Response.Status = "404 Not Found"
 Response.AddHeader("Location", "{your-path-to-your-404-page}")
于 2019-09-27T08:54:36.867 に答える