2008-12-07 16 views
74

Nachdem ich versucht habe, meine Site für die Google Webmaster-Tools einzurichten, habe ich festgestellt, dass meine benutzerdefinierte ASP.NET 404-Seite den 404-Statuscode nicht zurückgegeben hat. Es zeigte die korrekte benutzerdefinierte Seite an und sagte dem Browser, dass alles in Ordnung sei. Dies ist ein weicher 404 oder ein falscher 404. Google mag das nicht. So fand ich viele Artikel zu dem Thema, aber die Lösung, die ich wollte, schien nicht zu funktionieren.ASP.NET Custom 404 Rückgabe 200 OK statt 404 Nicht gefunden

Die Lösung, die ich arbeiten möchte, besteht darin, die folgenden zwei Zeilen dem Code hinter der Page_Load-Methode der benutzerdefinierten 404-Seite hinzuzufügen.

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

Dies funktioniert nicht. Die Seite gibt immer noch 200 OK zurück. Ich fand jedoch, dass, wenn ich den folgenden Code in den Entwurfscode fest einprogrammiere, es richtig arbeitet.

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

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

... Much more code ... 

</asp:content> 

Die Seite verwendet eine Masterseite. Und ich konfiguriere benutzerdefinierte Fehlerseiten in meiner web.config. Ich würde wirklich lieber den Code hinter Option verwenden, aber ich kann nicht scheinen, es funktioniert, ohne einen Hack-Inline-Code in das Design/Layout zu setzen.

+0

Was sagt der Browser? Ich benutze den Addon Header Spy für Firefox. –

+0

Header Spy Antwort: HTTP/1.1 404 Not Found Datum: So, 07 Dez 2008 06:21:20 GMT –

+0

Verwenden Sie eine Masterseite? Vielleicht ist es das. Ich werde eine Seite versuchen, ohne eine Masterseite zu verwenden ... –

Antwort

68

Lösung:

Das Problem, es stellte sich heraus, war die Verwendung der Masterseite. Ich habe es zum Laufen gebracht, indem ich den Statuscode später im Seitenlebenszyklus gesetzt habe, offensichtlich hat das Rendern der Masterseite es zurückgesetzt, also habe ich die Rendermethode übersteuert und sie gesetzt, nachdem das Rendern abgeschlossen war.

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

Mehr arbeiten könnte, um herauszufinden, genau durchgeführt werden, wenn der Master-Seite ist der Status Einstellung, aber ich werde es dich verlassen.


Original-Beitrag:

konnte ich einen Test-Web-App bekommen gut zu funktionieren, und es zumindest angezeigt, um die benutzerdefinierte Fehlerseite und hat einen 404-Statuscode. Ich kann Ihnen nicht sagen, was mit Ihrer App falsch ist, aber ich kann Ihnen sagen, was ich getan habe:

1) Bearbeitet die web.config für benutzerdefinierte Fehler:

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

2) es wurde eine 404.aspx Seite und stellen sie den Statuscode 404.

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

das ist über es, wenn ich auf jede Seite exte gehen nsion, die von Asp.Net verarbeitet wird und nicht existiert, mein Fiedler Protokoll zeigt deutlich eine 404, hier ist der Header:

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 

Nun, wenn ich auf eine Seite gehen, die von Asp nicht verarbeitet .Net, wie eine HTM-Datei, wird die benutzerdefinierte Seite nicht angezeigt und der von IIS konfigurierte 404 wird angezeigt.

Hier ist ein Beitrag, der in einige Details geht, die für Sie und Ihr Problem von Nutzen sein können, mein Test tut eine Umleitung auf die neue Seite, so dass die URL der angeforderten Datei ziemlich verloren ist (außer in die Abfragezeichenfolge).

Google 404 and .NET Custom Error Pages

Kopf Spy Antwort:

HTTP/1.1 404 Not Found 
Date: Sun, 07 Dec 2008 06:21:20 GMT 
+4

** Header Spy ** ist Addon _Header Spy für Firefox_ – Kiquenet

+0

Wie funktioniert das für statische '.html' benutzerdefinierte Fehlerseiten? – ebyrob

5

Nach zahlreichen Tests und Fehlerbehebung es scheint, dass bestimmte Hosting-Provider mit dem Return-Code stören können. Ich konnte das umgehen, indem ich einen "Hack" im Inhalt anwendete.

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

Dies ermöglicht die Seite den richtigen Rückgabecode egal was zurückzukehren.

27

Ich hatte ein ähnliches Problem möchte ich als 404 eine eigene Seite zeigen (die ASPX ist) und es funktionierte auf localhost in Ordnung, aber sobald ein Fern Besucher verbunden würden sie die allgemeine IIS 404.

erhalten Die Lösung dazu war hinzuzufügen

Response.TrySkipIisCustomErrors = true; 

Bevor Sie den Response.StatusCode ändern.

über Rick Strahl gefunden http://www.west-wind.com/weblog/posts/745738.aspx

9

Try Aufruf Response.End() Wiedergabe überspringen ...

Response.Status = "404 Not Found"; 
Response.StatusCode = 404; 
Response.End(); 
return; 
12

Die IIS 7-Lösung ist, einfach diese Datei zu Ihrer web.config hinzufügen:

<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

+3

Arbeitete für mich! Einzige Lösung hier, die funktioniert, wahrscheinlich aufgrund der Version, wie Sie es bemerken ... Beachten Sie: Sie können nur statische .htm-Dateien mit dieser Lösung verwenden. – squarecandy

+0

Das hat hervorragend funktioniert! Danke für die Lösung. –

0

ich war in der Lage zu umgehen Dieses Problem, indem Sie das folgende Setup in Asp.net-Webformularen mit .NET 3.5 verwenden.

Das Muster, das ich implementiert habe, umgeht die benutzerdefinierte Redirect-Lösung von .NET in der web.config, da ich meine eigene geschrieben habe, um alle Szenarien mit dem richtigen HTTP-Statuscode in der Kopfzeile zu behandeln.

Zuerst die Custom Abschnitt sieht web.config wie folgt aus:

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

Diese Einstellung sorgt dafür, dass Custom-Modus eingeschaltet ist, eine Einstellung wir später brauchen werden, und bietet ein All-else-Ausfall Option für die defaultRedirect von error.htm. Dies wird nützlich sein, wenn ich keinen Handler für den spezifischen Fehler habe oder etwas in Richtung einer unterbrochenen Datenbankverbindung ist.

Zweitens ist hier das globale asax Fehlerereignis:

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

Dieser Code passing off wird die Verantwortung für die Fehler in einer anderen Klasse der Handhabung. Wenn der Fehler nicht behandelt wird und CustomErrors aktiviert ist, bedeutet dies, dass wir einen Fall haben, in dem wir produktiv arbeiten und ein Fehler nicht behoben wurde. Wir werden es hier löschen, um zu verhindern, dass der Benutzer es sieht, aber melde es in Elmah an, damit wir wissen, was vor sich geht.

Die applicationErrorHandler Klasse sieht wie folgt aus:

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

Diese Klasse im Wesentlichen den Befehl Muster verwendet den entsprechenden Fehlerbehandlung für die Art des Fehlers zu finden, die ausgegeben wird. Es ist wichtig, Exception.GetBaseException() auf dieser Ebene zu verwenden, da fast jeder Fehler in eine höhere Ausnahme eingeschlossen wird. Wenn Sie z. B. "new System.Exception()" von einer beliebigen aspx-Seite auslösen, wird eine HttpUnhandledException auf dieser Ebene empfangen, keine System.Exception.

Die „Fabrik“ Code ist einfach und sieht wie folgt aus:

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

Am Ende, ich habe Schema Setup eine erweiterbare Fehlerbehandlung. In jedem der "Verhaltensweisen", die definiert sind, habe ich eine benutzerdefinierte Implementierung für den Fehlertyp. Zum Beispiel wird eine HTTP-Ausnahme für den Statuscode überprüft und entsprechend behandelt. Ein 404-Statuscode erfordert einen Server.Transfer anstelle von Request.Redirect zusammen mit dem entsprechenden Statuscode, der in der Kopfzeile geschrieben ist.

Hoffe, das hilft.